跨域问题的引入
在本地8000端口开启django程序,通过ajax往开启9000端口的django程序发送请求
8000端口的html文件
<input type="button" value="发送1" onclick="submitJsonp1();" /> <script src="/static/js/jquery-3.1.1.js"></script> <script> function submitJsonp1() { $.ajax({ url: 'http://127.0.0.1:9000/ajax1.html',type: 'GET',data: {nid:2},success:function (arg) { $('#content').html(arg); } }) } </script>
9000端口的接口
def ajax1(request): ret = {'status':True,'message': '....'} import json return HttpResponse(json.dumps(ret))
通过上图我们可以看到请求确确实实是发过去了,也拿到了结果。但是因为浏览器的同源策略结果没有拿到8000站点的范围里。
解决方式是利用src属性的跨域属性,程序员手动创建script标签,利用src属性去发请求,拿到请求结果后删除创建的这个script标签。
自定义script标签解决跨域
html
function submitJsonp2() { var tag = document.createElement('script'); tag.src = 'http://127.0.0.1:9000/xiaokai.html'; document.head.appendChild(tag); document.head.removeChild(tag); }
views.py
def xiaokai(request): return HttpResponse('ok')
我们发现返回的字符串已经到底script里面,此时script把ok当做一个变量,但是这个变量没有定义,所以报错。解决方式也很简单
后端返回的字符串ok用一个前端函数名包裹
def xiaokai(request): return HttpResponse('func("ok")')
前端多定义一个函数
function fuck(arg) { console.log(arg) $('#content').html(arg); }
此时console.log(arg) 就能正常显示字符串‘ok‘ 了
利用ajax的jsonp
html
function submitJsonp4() { $.ajax({ url: 'http://127.0.0.1:9000/xiaokai.html',type: 'POST',dataType: 'jsonp',jsonp: 'callback',jsonpCallback: 'func',success: function (arg) { console.log(arg) } }) }
真实发送的请求为http://127.0.0.1:9000/xiaokai.html?callback=func&_=1529415061035
定义success的好处是类似于匿名函数的概念,如果不设置success,那么就需要额外设置 jsonpCallback 指定的函数名,用了success就相当于万金油了
后端
def xiaokai(request): func = request.GET.get('callback') return HttpResponse('%s("xxoo")'%func)
jsonp的缺点
jsonp只能发get请求,要想支持所有的请求方式,需要用到cors