跨域
同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
何为同源:
协议,域名,端口都相同
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
Cors
参考博客:http://blog.csdn.net/u014344668/article/details/54948546
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。
浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
cors 两种请求: 简单请求与 预先请求
简单请求: 当请求同时满足下面两个条件时,浏览器会直接发送GET请求,在同一个请求中做跨域权限的验证。 请求方法是下列之一: GET HEAD POST 请求头中的Content-Type请求头的值是下列之一: application/x-www-form-urlencoded multipart/form-data text/plain ############ 预先请求 当请求满足下面任意一个条件时,浏览器会先发送一个OPTION请求,用来与目标域名服务器协商决定是否可以发送实际的跨域请求。 请求方法不是下列之一: GET HEAD POST 请求头中的Content-Type请求头的值不是下列之一: application/x-www-form-urlencoded multipart/form-data text/plain
浏览器在发现页面中有上述条件的动态跨域请求的时候,并不会立即执行对应的请求代码,而是会先发送Preflighted requests(预先验证请求),Preflighted requests是一个OPTION请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。
OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。
服务器收到OPTIONS请求后,设置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers头部与浏览器沟通来判断是否允许这个请求。
如果Preflighted requests验证通过,浏览器才会发送真正的跨域请求。
Jsonp
jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。
<script src="http://code.jquery.com/jquery-latest.js"></script>
自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#客户端
<button class="send_ajax">send_ajax</button>
<script>
//点击编写事件
$(".send_ajax").click(function () {
kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar") //自己组建的回调函数名为bar
});
//自己组建跨域的<script>标签
function kuayu_request(url) {
var $script=$("<script>"); // 创建script标签,是一个jquery对象: <script>
$script.attr("src",url);
$("body").append($script);
$("body script:last").remove();
}
//回调函数
function bar(arg) {
console.log(arg);
console.log(JSON.parse(arg));
}
</script>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def send_ajax(request):
import json
dic={"k1":"v1"}
print("callback:",request.GET.get("callback"))
callbacks=request.GET.get("callback")
return HttpResponse("%s('%s')"%(callbacks,json.dumps(dic)))
jQuery对JSONP的实现
getJSON
jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#客户端
<button onclick="f()">sendAjax</button>
<script>
function f(){
$.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){
alert("hello"+arg)
});
}
</script>
#fuwuduan 不改动。
结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。
$.ajax
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<script>
$(".send_ajax").click(function () {
$.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
dataType:"jsonp", // 跨域请求 <script>
jsonp: 'callbacks', //拼接回调函数,callbacks为键
jsonpCallback:"SayHi" //回调函数的函数名,SayHi为值
})
});
function SayHi(arg) { //回调函数
console.log("hello",arg)
}
</script>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json
def send_ajax(request):
func_name=request.GET.get("callbacks")
print("========",func_name) #jQuery32108857898425508359_1515120720532
s = {"name": "egon", "age": 122}
return HttpResponse("%s('%s')"%(func_name,json.dumps(s)))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<script>
$(".send_ajax").click(function () {
$.ajax({
url:"http://127.0.0.1:8000/send_ajax/",
dataType:"jsonp", // 跨域请求 <script>
jsonp: 'callbacks', //jQuery帮助随机生成的:callbacks="asdfadf1123141"
success:function (data) {
console.log(data)
}
})
});
</script>