二十五、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
posted @   Bruce_JRZ  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示