Django之JSONP(十八)
一、JSONP介绍
1.1 什么是JSONP
JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
JSONP:是一种请求方式,解决一些棘手的问题。JSONP只能发GET请求。
import requests request.get(‘http://www.baidu.com’) #往百度发一个get请求 request.post(‘http://www.baidu.com’) #往百度发一个post请求
1.2 使用原生js,或者jquery访问跨域报错
urls.py :
url(r'req/',views.req)
views.py :
from django.shortcuts import render import requests def req(request): response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') #print(response.content) #字节 response.encoding = 'utf-8' #print(response.text) #字符串 return render(request, 'req.html',{'result': response.text})
req.html :
<body> <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container> </div> <h1>后台获取结果</h1> {{ result }} <script> //原生js function getData(){ var xhr=new XMLHttpRequest() xhr.open("GET","http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301")//以什么方式a xhr.onreadystatechange=function(){//执行成功后的回调信息 console.log(xhr.responseText) } xhr.send() //发送信息 } </script> </body>
测试一下:
#从上图可以看到js跨域请求报错了。由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了所以通过script标签解决跨域请求的问题。
1.3 使用JSONP
req.html :
<body> <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container> </div> {# <h1>后台获取结果</h1>#} {# {{ result }}#} <script> function getData() { var tag = document.createElement("script"); tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403"; document.head.appendChild(tag); document.head.removeChild(tag); } function list(arg){ //因为上面的url里面callback=list,所以这里的函数名就叫做list,arg就是上面拿到的数据 console.log(arg); } </script> </body>
#这里主要是通过创建script标签来设置其属性src=远程地址,这样通过document.head.appendChild(tag)把创建的这个src标签添加到了head头里,加载的时候就已经执行了,加载的那一刻跨域请求就已经发出去了。document.head.removeChild(tag);防止一致累加,创建完标签获取到数据之后就删除掉。要返回的是js数据。
1.4 利用Jquery实现JSONP的方法:
<body> <h1>js直接获取结果</h1> <input type="button" value="获取数据" id="ok_button" onclick="getData();"> <div id=""container></div> <script src="/static/jquery-1.8.2.js"></script> <script> function getData() { $.ajax({ url: "http://www.jxntv.cn/data/jmd-jxtv2.html", type: 'GET', dataType: 'JSONP', jsonp:'callback', jsonpCallback: 'list' //这里的jsonp:'callback',jsonpCallback:'list相当于url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list", }) } function list(arg){ console.log(arg) } </script> </body>
#从上图可以看到效果是一样的。
优点:
1. 通过jsonp的传输方式我们可以绕开浏览器同源策略。
2. 页面不用刷新而获得数据
缺陷:
1. 远程数据的本地需要将数据封装在函数中
2. 本地需要定义被封装的函数
3. JSONP只能发送GET请求