二十五、JSON跨域
web项目中,向其它ip地址发送请求时会受到浏览器同源策略的限制 : 对方受到请求,并作出响应,但浏览器限制了接受响应。
# 受到同源策略的限制
$.ajax({
url:'http://127.0.0.1:9000/ajax_jsonp.html',
type:'GET',
data:{},
success:function(arg) {
// 收不到
}
})
# 127.0.0.1:9000的视图函数
def ajax_jsonp(request):
print(".....")
return HttpResponse("abcdefg")
127.0.0.1:9000实际有走到ajax_jsonp函数。但浏览器报错:
# blocked by CORS policy
Access to XMLHttpRequest at 'http://127.0.0.1:9000/ajax_jsonp.html'
from origin 'http://127.0.0.1:8000' has been blocked by CORS policy
: NO 'Access-Control-Allow-Orign' header is present on the requested
resource.
XMLHttpRequest 遵循该策略。
解决办法:Iframe标签 img标签 Script标签 这些有scr属性的可突破同源策略
创建script标签,将需要访问的url给src属性赋值,这时点击页面按钮,触发函数:
# script标签突破同源策略
function submitJsonp2() {
var tag = document.createElement('script');
tag.src = 'http://127.0.0.1:9000/iamother.html';
# 添加tag,从而发送请求。然后马上移除tag
document.head.appendChild(tag);
document.head.removeChild(tag);
}
这时,浏览器依然报错: 返回的字符串is not defined
Uncaught ReferenceError: abcdefg is not defined
报错原因是返回的数据不是js
修改127.0.0.1:9000项目的响应:数据外层包裹一个函数名
# 127.0.0.1:9000的视图函数
def ajax_jsonp(request):
print(".....")
return HttpResponse("dd('abcdefg');")
当前页面html定义相同名字的函数:
# html
function dd(arg){
console.log(arg); # ajax_jsonp请求返回的数据就在这里拿到
}
以上这种随机生成一个script 加在head上,然后又移除的方式 叫做JSONP
# Ajax提供了jsonp的方式
$.ajax({
url:'http://127.0.0.1:9000/ajax_jsonp.html',
type:'GET',
dataType: 'jsonp',
})
完善:
在url后拼接参数callback=.....
对方接收请求,从callback参数获得指定的函数名,在返回数据时,用指定的函数名包裹数据返回 :
# 从callback参数获得指定的函数名
def ajax_jsonp(request):
name = request.GET.get('callback')
return HttpResponse("%s('abcdefg');"%(name))
# 使用ajax时这样传callback参数:
$.ajax({
url:'http://127.0.0.1:9000/ajax_jsonp.html',
type:'GET',
dataType: 'jsonp',
jsonp:'callback',
jsonpCallback:'list',
})
注意:jsonp只能发get请求。改type=POST都不起作用。因为本质是设置标签的src
JSONP:利用创建script块,在其中执行src属性为:远程url
跨域的另一种方式:CORS
#设置响应头,让浏览器允许通过
def cors_test(request):
obj = HttpResponse('faadssa')
obj['Access-Control-Allow-Origin'] = '*'
return obj

浙公网安备 33010602011771号