JSONP(JSON with Padding)是JSON的一種「使用模式」,可用於解決主流瀏覽器的跨域數據訪問的問題。因爲同源策略,通常來講位於 server1.example.com 的網頁沒法與不是 server1.example.com的服務器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並非 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
原理:javascript
只能發GET請求html
處理文件:java
import requests def jsonp(request): # 獲取url信息 response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') response.encoding = 'utf-8' # 進行編碼 return render(request,'jsonp.html',{'result':response.text}) # response.text 請求內容
HTML文件:python
<body> <h1>後臺獲取的結果</h1> {{ result }} <h1>js直接獲取結果</h1> <input type="button" value="獲取數據" onclick="getContent();" /> <div id="container"></div> <script src="/static/jquery-1.8.2.js"></script> <script> function getContent() { var xhr = new XMLHttpRequest(); // 建立對象 xhr.open('GET', 'http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301'); // GET方式打開 xhr.onreadystatechange = function () { // 收到返回值時執行 console.log(xhr.responseText); }; xhr.send() // 發送 } </script> </body>
注:點擊js直接獲取結果時,瀏覽器顯示下面報錯信息,因爲瀏覽器只接受http://127.0.0.1:8000發過來的信息,對於天氣網站發過來的信息直接屏蔽掉了,這就是同源策略,那有沒有什麼方式能夠解決?jquery
XMLHttpRequest cannot load http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301. 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標籤不受同源策略的影響web
處理文件:ajax
import requests def jsonp(request): # 獲取url信息 response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') response.encoding = 'utf-8' # 進行編碼 return render(request,'jsonp.html',{'result':response.text}) # response.text 請求內容 def jsonp_api(request): return HttpResponse('alert(123)')
HTML文件:sql
<body> <h1>後臺獲取的結果</h1> {{ result }} <h1>js直接獲取結果</h1> <input type="button" value="獲取數據" onclick="getContent();" /> <div id="container"></div> <script> function getContent() { var tag = document.createElement('script'); tag.src = '/jsonp_api.html'; document.head.appendChild(tag); // document.head.removeChild(tag); } </script> </body>
注:js請求時爲了方便,仍是請求的是當前程序url;執行完上面代碼會發現一個神奇的情況,頁面會彈出123信息,代表script獲取信息成功 數據庫
處理文件:django
def jsonp(request): return render(request,'jsonp.html') # response.text 請求內容 def jsonp_api(request): func = request.GET.get('callback') # 獲取用戶callback參數 content = '%s(10000)'%func # 執行func(10000)函數 return HttpResponse(content)
HTML文件:
<body> <h1>後臺獲取的結果</h1> {{ result }} <h1>js直接獲取結果</h1> <input type="button" value="獲取數據" onclick="getContent();" /> <div id="container"></div> <script> function getContent() { var tag = document.createElement('script'); tag.src = '/jsonp_api.html?callback=list'; // 自定義callback參數,與後臺達成默契 document.head.appendChild(tag); // document.head.removeChild(tag); } function list(arg){ // 自定義函數與callback=list相對應 alert(arg); } </script> </body>
注:js發請求時,帶上callback參數,而後定義參數對應的方法,後臺會把數據傳入此方法內而且執行執行;至於要打印仍是彈框,就看用戶本身的需求去處理了;jsonp的原理和實現過程就是上述代碼的實現
處理文件:
import requests def jsonp(request): response = requests.get('http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403') response.encoding = 'utf-8' # 進行編碼 return render(request, 'jsonp.html', {'result': response.text}) # response.text 請求內容
HTML文件:
<body> <h1>後臺獲取的結果</h1> {{ result }} <h1>js直接獲取結果</h1> <input type="button" value="獲取數據" onclick="getContent();" /> <div id="container"></div> <script src="/static/jquery-1.8.2.js"></script> <script> function getContent() { $.ajax({ url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403', type: 'POST', dataType: 'jsonp', // 即便寫的type是POST也是按照GET請求發送 jsonp: 'callback', jsonpCallback: 'list' }); } function list(arg){ // 自定義函數與callback=list相對應 console.log(arg); var data = arg['data']; for(k in data){ var tr = document.createElement('td'); var week = data[k]['week']; var list = data[k]['list']; tr.textContent =week document.body.appendChild(tr); console.log(week); for(i in list){ var name = list[i]['name']; console.log(name) }}} </script> </body>
網站獲取到的數據
list({data:[ { "week":"週日", "list":[ { "time":"0030", "name":"通宵劇場六集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市現場》60分鐘精編版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快樂生活一點通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨報》60分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精選劇場四集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地寶當家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《誰是贏家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性劇場三集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快樂生活一點通》精編版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地寶當家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市現場》90分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情緣》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚間800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市劇場》黃金劇(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市劇場》黃金劇(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新聞聯播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚劇場", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] }, { "week":"週一", "list":[ { "time":"0030", "name":"通宵劇場六集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市現場》60分鐘精編版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快樂生活一點通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨報》60分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精選劇場四集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地寶當家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《誰是贏家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性劇場三集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快樂生活一點通》精編版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地寶當家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市現場》90分鐘直播版塊", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情緣》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚間800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市劇場》黃金劇(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市劇場》黃金劇(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新聞聯播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚劇場", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"週二", "list":[ { "time":"0030", "name":"通宵劇場六集連播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市現場》60分鐘精編版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, {