浏览器可以向其他服务器发送数据,但是默认不会接收从其他服务器返回的数据,这叫做浏览器的同源策略,即XMLHttpRequest无法接收其他服务器的数据。但在实际生活场景中经常需要向其他服务器发送数据,这就需要用到jsonp实现跨域。
<!--直接向其他服务器发送数据返回的报错信息--> XMLHttpRequest cannot load http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 405.
jsonp的使用是基于,具有src属性的标签,例如img标签、script标签,它们不遵守浏览器的同源策略,可以接受从其他服务器返回的数据。
1.利用script标签不遵守同源属性手动从远程服务器获取数据
<div id="content">原始内容</div> <input type="button" value="jsonp发送" onclick="submitJsonp2()">
function submitJsonp2() { var tag = document.createElement('script'); //创建script标签 tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'; //指定script标签的src属性为远程服务器地址 document.head.appendChild(tag); //在head部分增加创建的script标签,获取访问的远程服务器地址的返回内容 document.head.removeChild(tag); //删除创建的script标签 } //由于远程服务器的返回值由list函数包裹,因此在本地需要创建一个list函数 function list(arg) { $('#content').html(JSON.stringify(arg)) //将远程服务器的返回值显示到当前页面 }
2.直接使用jQuery
<div id="content">原始内容</div> <input type="button" value="jsonp发送" onclick="submitJsonp3()">
function submitJsonp3() { $.ajax({ url:'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403', type:'POST', dataType:'JSONP', jsonp: 'callback', jsonpCallback:'func' }) } function func(arg) { $('#content').html(JSON.stringify(arg)) }
dataType:'JSONP'指定数据格式为JSONP,则整个ajax请求不会通过XMLHttpRequest对象向后台发送,而是在页面创建script标签并获取远程服务器的返回数据,再将创建的script标签删除。
jsonp和jsonpCallback参数相当于指定回调参数名称为func,在远程服务器通过request.GET.get('callback')获取回调函数的名称再包裹到返回值上,即name = request.GET.get('callback'),return HttpResponse('%s("返回值")'%name)
使用jsonp形式时,无论type指定为get还是post,实际都会转换为get形式发送。