1. json 是一種數據格式, jsonp 是一種數據調用的方式。你能夠簡單的理解爲 帶callback的json就是jsonp。css
2. Python裏面有個模塊requests, requests.get('http://www.baidu.com')。把這段代碼放到程序裏面html
3.建立app02備用:在terminal端輸入 python manage.py startapp app02, 導入requests模塊。前端
4. 這是一個關於天氣狀況的網址:http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityID=101121301。咱們嘗試用python
requests.get 方法在頁面上拿到它。
urls.py中寫對應關係jquery
from django.conf.urls import url from django.contrib import admin from app01 import views from app02 import views as a2 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^req/', a2.req), url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html', views.article,name='article'), ]
views.pyweb
req.html中寫前端ajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{result}} </body> </html>
頁面效果:django
5. 瀏覽器沒有直接向天氣接口發請求,而是向咱們本身的URL發送了請求,咱們本身的URL內部經過模塊向遠程進行發送了。因此說瀏覽器沒有直接接觸外部請求。json
6. 嘗試經過jQuery的ajax方法,越過中間的server,讓瀏覽器直接發請求至天氣接口。後端
7. 寫req.html頁面以下,用XMLHttpRequest來實現。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>後臺獲取的結果</h1> {{result}} <h1>js直接獲取的結果</h1> <input type="button" value="獲取數據" onclick="getContent();"/> <div id="container"></div> <script> function getContent(){ var xhr=new XMLHttpRequest(); xhr.open('GET','http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityID=101121301') xhr.onreadystatechange=function(){ console.log(xhr.responseText); }; xhr.send(); } </script> </body> </html>
運行結果:
8. 上述兩種方法進行比較:第1種方法,沒有通過瀏覽器,往別的域名發請求是容許的;第2種方法,通過了瀏覽器發請求是不容許的。
因爲瀏覽器具備同源(本域名)策略,阻止了ajax請求。經過巧妙的機制能夠繞開這個限制。
例如:<script src="//cdn.bootcss.com/jquery/3.1.1/core.js"></script> 就能夠越過瀏覽器的這個限制。凡是具備src屬性的標籤都不受瀏覽器同源策略的影響。
9. 向我本身寫的另一個網站(另外的域名)發請求,默認也會受同源策略的阻止。下面經過實驗驗證。
9.1: 寫URL
9.2: 寫後端。
9.3: 修改端口。
9.4: 打開,查看可用的域名。
9.5:
9.6:把域名添加到allower_host裏面。
9.7: 直接訪問沒有報錯。
9.8:經過瀏覽器給本身發請求。
9.9: 以GET方式向別的域名發請求。
9.10:
10. 用一個巧妙的方法來解決
var tag=document.createElement('script');-------建立一個script標籤。
tag.src='http://wupeiqi.com:8001/jsonp.html?k1-v1&k2=v2'; -------向這個地址發請求。
document.head.appendChild(tag);--------把script標籤放到head裏面。
修改req.html以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>後臺獲取的結果</h1> {{result}} <h1>js直接獲取的結果</h1> <input type="button" value="獲取數據" onclick="getContent();"/> <div id="container"></div> <script> function getContent(){ /* var xhr=new XMLHttpRequest(); xhr.open('GET','http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityID=101121301') xhr.onreadystatechange=function(){ console.log(xhr.responseText); }; xhr.send(); */ var tag=document.createElement('script'); tag.src='http://wupeiqi.com:8001/jsonp.html?k1-v1&k2=v2'; document.head.appendChild(tag); } </script> </body> </html>
頁面效果:
11. 既然XMLHttprequest對象會受瀏覽器的影響,那麼咱們本身建立一個script標籤放到這裏就能夠了。雖然訪問成功了,可是返回的「OK」卻沒有意義,還會引發報錯。
修改返回的內容,查看效果:
12. 到目前爲止,經過JScript實現了跨域請求。返回的數據必須是符合JS格式的。
13. 目前爲止,尚未變量去接收返回的數據。返回的字符串就叫:「callback( XXXX)」,至關於調用一個你本身寫的那個callback函數。
100000至關於callback函數的實參。
因此須要本身定義一個callback函數
頁面效果:拿到了這個返回的值。
14. 把callback函數改爲一個動態的函數名。這樣就能夠區分不一樣的客戶了。訪問的時候就把本身的函數名也傳過去。
func=request.GET.get('call')
return HttpResponse('call(1000000)')
頁面效果:同上,沒有報錯。也返回了100000
15. 執行完之後,應該把script標籤移除掉,讓程序恢復原狀。
document.head.removeChild(tag);
JSONP是用的最爲普遍的跨域請求。
訪問效果:
16. 通常狀況下,函數名的key都叫callback,callback=要執行的那個函數名(例如:callback=list)。下面看一個示例,江西電視臺的一個節目單。
17. JSONP只能發GET請求,不能發POST請求。由於全部的參數都放到了URL中的?後面了。
tag.src='http://wupeiqi.com:8001/jsonp.html?callback=list&k2=v2'
至關於經過JSONP僞造了一個ajax請求。上面的方式是經過原生的JS來寫的。
下面講怎麼樣經過jQuery的來寫。
url:'http://www.jxntv.cn/data/jmd-jxtv2.html',
type:'POST',
dataType:'jsonp', 表示讓$.ajax內部以jsonp的形式來發送請求。
jsonp:'callback', 兩句合起來至關於callback=list
jsonpCallback:'list', 兩句合起來至關於callback=list
req.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>後臺獲取的結果</h1> {{result}} <h1>js直接獲取的結果</h1> <input type="button" value="獲取數據" onclick="getContent();"/> <div id="container"></div> <script src="/static/jquery-1.12.4.js"></script> <script> function getContent(){ /* var xhr=new XMLHttpRequest(); xhr.open('GET','http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityID=101121301') xhr.onreadystatechange=function(){ console.log(xhr.responseText); }; xhr.send(); */ /* var tag=document.createElement('script'); tag.src='http://wupeiqi.com:8001/jsonp.html?k1-v1&k2=v2'; document.head.appendChild(tag); */ $.ajax({ url:'http://www.jxntv.cn/data/jmd-jxtv2.html', type:'POST', dataType:'jsonp', jsonp:'callback', jsonpCallback:'list', }) } </script> </body> </html>
頁面正常得到告終果
18. 容許某個域名進行訪問。參考以下的老師博客。