---------------------------------------前言------------------------------------------------
一般来说,我们的浏览器在访问一个服务器之后,就只会和这一个服务器进行交互;
浏览器存在一个同源策略,那它是什么呢?
之前我们也遇到过,比如说:
我们在第一次访问服务器的时候url是127.0.0.1:8080/index
第二次我们访问的时候一般是直接写/ajax/
那第二次访问怎么知道向哪个服务器发送请求呢?这里用到的就是浏览器的同源策略:
在一个完整url请求服务器后,第二次如果要访问同一个服务器,不需要在写ip地址和端口号,浏览器会自动补全发送请求,这里浏览器的同源策略带来的一个好处。
但是如果第二次我们要访问别的服务器,比如说127.0.0.1:9090,结果会怎么样呢?
首先是能够成功发送请求并有响应的,但是到了浏览器之后,浏览器检测到和之前的数据来源不同,它的同源策略会直接把数据截断,就造成了跨域访问无效的结果,这是浏览器的同源策略带给我们的不好的地方
那我们要怎么跨域访问呢?一个想法就是关掉同源策略,但是不仅好处没了,而且也关不掉。那另一个想法就是绕过浏览器的同源策略
怎么绕过呢?首先我们要知道同源策略的作用对象,那就是Xmlhttprequest
对象,所有发送请求的本质都是它,但是还记得html里面有一些标签,比如说script
iframe
img
,它们里面有固有属性src
,这个属性不被同源策略限制。不如img 可以从任何地方拿到图片。那就有了方向,这里我们是把script标签中的src属性伪造成请求,目标服务器做一些简单的特殊处理,就可以实现跨域请求,这种方法我们叫做**Jsonp
**
-------------------------------正文----------------------------------------
原理实现:
html部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content"></div>
<input type="button" value="发送" id="submit">
<script>
document.getElementById("submit").onclick=function () {
var tag=document.createElement("script");
tag.src="http://127.0.0.1:9090";
document.head.appendChild(tag);
document.head.removeChild(tag);
};
function callback(arg) {
document.getElementById("content").innerText=arg
}
</script>
</body>
</html>
跨域服务器处理部分:
def jonsp(resquest):
return HttpResponse('callback("这是跨域请求");')
总结:上诉方式要实现跨域请求,双方要把包裹数据的函数名统一,这种方式不灵活
Jqury下的Jsonp:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="content"></div>
<input type="button" value="发送" id="submit">
<script src="/static/jquery-3.1.1.min.js"></script>
<script>
$("#submit").click(function () {
$.ajax({
url:"http://127.0.0.1:9090",
method:"GET", //无所谓自己写什么,因为只能用Get,写了POST也用的GET。因为csrf的存在导致的,跨域Ajax请求只能用GET请求
dataType:"jsonp", //重点,实现原理部分
jsonp:"callback", //相当于http://127.0.0.1:9090?callback=func
jsonpCallback:'func'
});
});
function func(arg) {
$("#content").text(arg);
console.log(5555);
console.log(arg)
}
</script>
</body>
</html>
跨域服务器处理部分:
def jonsp(resquest):
callback=resquest.GET.get("callback")
return HttpResponse("%s('这是跨域请求');"%(callback,))
总结:
jQuery帮我们封装好了jsonp方法,而且有了一个约定,不再需要跨域服务器写死了包裹数据的函数名