提起跨域,我們要先了解一下同源政策,需要明確一點的是,同源政策是針對於瀏覽器的,不是針對js
同源策略限制從乙個源載入的文件或指令碼如何與來自另乙個源的資源進行互動。這是乙個用於隔離潛在惡意檔案的關鍵的安全機制。--mdn通俗來講就是瀏覽器出於安全方面的考慮,只允許與本域下的接**互。不同源的客戶端指令碼在沒有明確授權的情況下,不能讀寫對方的資源。那麼怎樣是同源呢?
同源指的是:
以為例
該url的協議為https,網域名稱是plainnany.github.io,埠為443,預設埠可以省略。
那麼問題來了,我就是想訪問其他域(非同源)的資源----即跨域,該怎麼做呢?
常用的跨域方法有jsonp,cors,postmessage等,
jsonp是json with padding(填充式json或引數是json)的簡寫,是應用json的一種新方法,jsonp看起來和json差不多,只不過是被包含在函式呼叫的json,像這樣:callback()。
我們知道html中script通過src屬性可以引入其他域下的js,比如引入線上的jquery庫。也可以引入非js的檔案,利用這個特性,可實現跨域訪問介面。該方法需要後端支援。
定義資料處理函式_fun
建立script標籤,src的位址執行後端介面,最後加個引數callback=_fun
服務端在收到請求後,解析引數,計算返還資料,輸出 fun(data) 字串。
fun(data)會放到script標籤做為js執行。此時會呼叫fun函式,將data做為引數。
以下面例子為例,我們用nodejs監聽後端檔案,同時在本地開啟前端頁面來模擬跨域。
前端頁面
// 傳送請求
後端頁面
res.end(`$($)`) // 伺服器收到請求後,解析引數,
// 將callback(data)以字串的形式返還資料,前端頁面會將callback(data)作為js執行
// 呼叫jsonpcallback(data)函式。
}).listen(3000, '127.0.0.1');
console.log('啟動服務,監聽 127.0.0.1:3000');
jsonp跨域不像下面的cors跨域那樣受同源政策的影響,而且相容性也比較好,但jsonp跨域也有其缺點,主要表現在:
它支援 get 請求而不支援 post 等其它類行的 http 請求。
它只支援跨域 http 請求這種情況,不能解決不同域的兩個頁面或 iframe 之間進行資料通訊的問題
jsonp從其他域中載入**執行,如果該域不安全並且夾帶一些惡意**,會存在安全隱患
要確定jsonp請求是否失敗並不容易
cors 全稱是跨域資源共享(cross-origin resource sharing),是一種 ajax 跨域請求資源的方式,支援現代瀏覽器,ie支援10以上。 實現方式很簡單,當你使用 xmlhttprequest 傳送請求時,瀏覽器發現該請求不符合同源策略,會給該請求加乙個請求頭:origin,後台進行一系列處理,如果確定接受請求則在返回結果中加入乙個響應頭:access-control-allow-origin; 瀏覽器判斷該相應頭中是否包含 origin 的值,如果有則瀏覽器會處理響應,我們就可以拿到響應資料,如果不包含瀏覽器直接駁回,這時我們無法拿到響應資料。所以 cors 的表象是讓你覺得它與同源的 ajax 請求沒啥區別,**完全一樣。
cors又分簡單請求和非簡單請求
簡單請求:
比如傳送了乙個origin的頭部
如果伺服器認為這個請求可以接受,就在access-control-allow-origin頭部回發相同的源資訊
比如傳送了乙個origin的頭部
如果伺服器認為這個請求可以接受,就在access-control-allow-origin頭部回發相同的源資訊
access-control-allow-origin : http:
詳見阮一峰 cors通訊
我們用nodejs監聽後端檔案,用http-server開啟前端檔案來模擬跨域
前端
後端**
res.end('用cors跨域成功')
}).listen(3000, '127.0.0.1')
console.log('啟動服務,監聽 127.0.0.1:3000')
cors 的優缺點:
使用簡單方便,更為安全
支援 post 請求方式
cors 是一種新型的跨域問題的解決方案,存在相容問題,僅支援 ie 10 以上
當兩個頁面不同域,但是它們的父域之上都相同(埠),那麼可以使用降域的方法來實現跨域。
對於主域相同而子域不同的情況下,可以通過設定 document.domain 的辦法來解決,
具體做法是可以在url為a.nany.com:8080下的a.html 和b.nany.com:8080下的b.html 兩個檔案分別加上 document.domain = "nany.com";然後通過 a.html 檔案建立乙個 iframe,去控制 iframe 的 window,從而進行互動,當然這種方法只能解決主域相同而二級網域名稱不同的情況。
首先配置系統的hosts檔案,如果你的git bash安裝的不是在c盤,千萬不要直接去找 /etc下的hosts檔案。
如我的是在
然後新增
用http-server監聽,在瀏覽器輸入 或者 即可實現跨域
JS中實現跨域的方法總結
今天早上在地鐵看了點基礎知識的考察題,看到了乙個js跨域的問題,仔細想了想自己腦子裡竟然只剩下jsonp跨域和用nginx反向 進行跨域,想著還有別的幾種方法,就是想不起來,這個人呢,一上歲數這個腦子就不好使,為了防止下次又遺忘了,所以特意寫一篇隨筆來記錄一下js中實現跨域的方式 1.jsonp請求...
js跨域及解決方法
前段時間做重構公司 的時候需要跨域訪問我們這邊其他系統的介面,由於那邊的介面都是採用webservice的方式返回json的形式提供的,正好他們那邊還提供的ajax的使用示例,就懶得在跑到後台去傳遞了,直接前台用ajax了。結果一直沒有效果,chrome除錯的時候報出這樣的提示xmlhttprequ...
js中的跨域方法總結
什麼是跨域?瀏覽器的安全策略,只要協議,網域名稱,埠有任何乙個不同,就被當做不同的域。下面對的同源檢測 a.html 同源 b.html 同源 8080 不同源 不同源 不同源 1,jsonp方法 2,document.domain 原理 document.domain設定成相同的網域名稱,來訪問i...