同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,若是缺乏了同源策略,则浏览器的正常功能可能都会受到影响。能够说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。javascript
所谓同源是指,域名,协议,端口相同。若是非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。css
client:http://127.0.0.1:8000html
<!-- 前端页面 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>index</h3> <button class="get_service">服务</button> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> $(".get_service").click(function () { $.ajax({ url: "http://127.0.0.1:8001/service/", success: function (data) { console.log(data); } }); }); </script> </body> </html>
# views.py def index(request): return render(request, "index.html")
service:http://127.0.0.1:8001前端
# views.py def service(request): info = {"name": "egon", "age": 34, "price": 200} return HttpResponse(json.dumps(info))
当在 client 上按下按钮,会报以下错误 (在火狐浏览器中查看) :java
此时查看 service 端,发现请求已经发生,是浏览器对非同源请求返回的结果作了拦截。python
JSONP 是 JSON 用来跨域的一个东西。原理是经过 script 标签的跨域特性来绕过同源策略。jquery
JSONP 的原型:建立一个回调函数,而后在远程服务上调用这个函数而且将 JSON 数据形式做为参数传递,完成回调。将 JSON 数据填充进回调函数,这就是 JSONP 的 JSON+Padding 的含义。git
客户端在 AJAX 发送数据的时候改变其 dataType 属性的值为 jsonp ,并增长一个属性 jsonp: "callbacks" 便可。github
$(".get_service").click(function () { $.ajax({ url: "http://127.0.0.1:8001/service/", type: "get", dataType: "jsonp", // 伪造ajax 基于script jsonp: "callbacks", success: function (data) { console.log(data); } }); });
服务端的视图函数中将所需数据以回调函数的形式返回:ajax
def service(request): info = {"name": "egon", "age": 34, "price": 200} func = request.GET.get("callbacks") return HttpResponse("%s('%s')" % (func, json.dumps(info)))
CORS 是最经常使用的方式,其方法比 JSONP 简单,客户端无需改动,只需在服务端加上 response["Access-Control-Allow-Origin"] 头就行。其值赋值为容许访问的源,即地址和端口号,若是赋值为 "*" ,表明全部源均可访问。
def service(request): info = {"name": "egon", "age": 34, "price": 200} response = HttpResponse(json.dumps(info)) response["Access-Control-Allow-Origin"] = "*" return response
经过一个接口获得以 JSONP 回调函数形式的数据,对其进行整理获得一周内天天的节目列表。
// 实例应用 $(".get_service").click(function () { $.ajax({ url: "http://www.jxntv.cn/data/jmd-jxtv2.html", type: "get", dataType: "jsonp", // 伪造ajax 基于script jsonp: "callbacks", jsonpCallback: "list", success: function (data) { {#console.log(data.data);#} var html = ''; $.each(data.data, function (index, weekday) { html += '<p>'+ weekday.week +'</p>'; $.each(weekday.list, function (j, show) { html += '<p><label>'+ show.time +'</label> <a href='+ show.link +'>'+ show.name +'</a></p>'; }); }); $("body").append(html); } }); });
GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/9day85