36)django-jsonp跨域
一:什么是JSONP
JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
二:使用原生js,或者jquery访问跨域报错
<body> <h1>后台获取结果</h1> {{ result }} <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container> </div> <script> //原生js function getData(){ var xhr=new XMLHttpRequest() xhr.open("GET","http://127.0.0.1:8001/req")//以什么方式a xhr.onreadystatechange=function(){//执行成功后的回调信息 console.log(xhr.responseText) } xhr.send() //发送信息 } </script> </body> #js发错报错 XMLHttpRequest cannot load http://127.0.0.1:8001/req. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. 以把请求放过去了,也收到了,但在在数据回到浏览器的时候,我浏览器拒不接受。这是浏览器策略。
三:使用script发送数据
#jsonp 存在的意义就是:由于浏览器具有同源策略(阻止ajax请求,但是无法阻止script)。 #通过script发送数据。 <body> <h1>后台获取结果</h1> {{ result }} <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container> </div> <script> //原生js function getData(){ var tag=document.createElement("script") //创建script标签 tag.src="http://127.0.0.1:8001/req //要发送地址 document.head.appendChild(tag)//script加入头部 } </script> </body>
#但是返回结果会出错,原因返回的结果不是script语法,所以要把返回结果必须是JS格式 return HttpResponse("alter(123)") 正确 return HttpResponse("123")报错。
四:例子
#例子:通过script跨哉访问请求(js发送数据) 工程2: #views.py from django.shortcuts import render,HttpResponse # Create your views here. def req(request): func=request.GET.get("func") return HttpResponse('func("XXX")') #返回func是js定义的函数 #urls.py url(r'^req$',views.req), #起动地址 http://127.0.0.1:8001/req 工程1: #views.py from django.shortcuts import render,HttpResponse import requests # Create your views here. def a(request): return HttpResponse("ok") #urls.py #url(r'^a/', views.a), #模板 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container> </div> <script> //原生js function getData(){ var tag=document.createElement("script") //创建script标签 tag.src="http://127.0.0.1:8001/req?func=func" //要发送地址 document.head.appendChild(tag)//script加入头部 } #func=func 把js方法传递给后台 function func(arg){ alert(arg); } </script> </body> </html>
五:JSONP跨域请求的本质
由于浏览器具有同源策略(阻止ajax跨域请求,但是无法阻止script) 1)创建script标签 2)src=远程地址 3)返回的数据必须是js格式 JSONP只能发GET请求
六:jquery跨域实现
#jsonp跨域请求jquery方式 <script src="/static/jquery-1.12.4.js"></script> <script> //原生js $.ajax({ url:"http://127.0.0.1:8001/req?", type:"POST", dataType:"jsonp", jsonp:"callback",//发送的参数 jsonpCallback:"func",//发送参数的值 等价http://127.0.0.1:8001/req?callback=func }) } function func(arg){ alert(arg); } </script>
七:总结
就是利用script标签绕过同源策略,获得一个类似这样的数据,jsonpcallback是页面存在的回调方法,参数就是想得到的json。