同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。使用jsonp实现跨域请求共有2中方式。
第一种:
一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。
利用script标签进行引入,同时使用回调函数来获取跨域的数据。
首先请求端的前端代码:
<script>
//回调函数
function sky(arg){
console.log(arg);
console.log(typeof arg);
var data=JSON.parse(arg);
console.log(data);
console.log(typeof data);
}
//创建一个script标签并将请求的路径和回调函数的名称加入进去
function get_jsonp_data(url) {
var ele_script=$("<script>");
ele_script.attr("src",url);
ele_script.attr("id","jsonp");
$("body").append(ele_script);
$("#jsonp").remove() //引入后马上就会执行回调函数故可以立即删掉
}
$(".get_service2").click(function () {
get_jsonp_data("http://127.0.0.1:8001/service/?callbacks=sky")
})
</script>
被请求端的后端代码:
def service(request):
func = request.GET.get("callbacks") # 获取回调函数的名称
print("func:",func)
info = {"name": "egon", "age": 34, "price": 200} # 待发送的数据
print(info)
return HttpResponse(" %s('%s')"%(func,json.dumps(info))) # 返回前端调用对应的回调函数
这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。
第二种:
我们可以使用JavaScript动态生成script标签来进行跨域请求同时也可以直接使用ajax方式(jQuery形式)进行跨域请求。
首先请求端的前端代码:
$(".get_service3").click(function () {
$.ajax({
url: "http://127.0.0.1:8001/service",
type:"get",
dataType:"jsonp", // 期望得到的数据类型
jsonp:'callbacks', //可以动态生成回调函数的名称并且调用它
success:function (data) {
console.log(data)
}
})
})
被请求端的后端代码:
def service(request):
func = request.GET.get("callbacks") # 获取回调函数的名称
print("func:",func)
info = {"name": "egon", "age": 34, "price": 200} # 待发送的数据
print(info)
return HttpResponse(" %s('%s')"%(func,json.dumps(info))) # 返回前端调用对应的回调函数