前言
這幾天的工作中,碰到了乙個完全不同域之間的跨域問題,發現自己竟然無法確定能不能實現跨域,可見基礎知識完全被拋之腦後了,趁週末整理一下。為什麼會存在跨域
跨域是因為瀏覽器有同源策略,同源策略的定義是協議、網域名稱、埠都要一致。 在跨域的情況下,瀏覽器出於安全考慮,會限制不同域之間的資料或dom互動行為,如:cookie、localstorage 和 indexdb 無法讀取。
dom 無法獲得。
ajax 請求不能傳送。
關於同源策略的具體概念請參考mdn。
為什麼需要同源策略呢。那我們試想一下如果瀏覽器沒有同源策略的情況。打個最基本的比方,現在你新建了乙個站點:
假如沒有跨域限制,那是不是可以隨便讀取天貓的cookie,localstorage, indexdb 等資訊,如果這些資訊裡有使用者名稱和密碼或其他敏感資訊,剛好又沒有加密的話,那豈不是都能拿到,這怎麼可能。
假如沒有跨域限制,你把iframe的src指向天貓,讓使用者去登陸,然後你就可以獲取iframe裡面的dom元素,那豈不是賬號密碼唾手可得。可以訪問dom的話,只要iframe引入其他公司的站點,想怎麼改就怎麼改,那好多公司都要倒閉了。
假如沒有跨域限制,就可以向天貓等站點發請求,那豈不是可以隨便提交別人的訂單。這明顯不合理啊。世界會亂。
但跨域問題總要解決的,因為有時候業務中確實需要跨域
下面列出八種跨域解決方案
jsonp原理:使用script標籤,src的值為後端某個檔案,加上callback引數。返回一段js字串。
複製**缺點:只能用於 get 請求。如果需要 post,可以試試用 form 提交來 hack。
document.domain原理:通過設定document.domain來跨域。
缺點:只適用於主域相同,子域不同的業務場景。
hash原理:利用hash改變,頁面不會重新整理的特點。父視窗在iframe的src上增加hash值,並在子視窗監聽 hashchange事件。
缺點:只能通過 hash 傳遞有效資訊, 只能設定字串型別。
window.name原理:在乙個視窗(window)的生命週期內,視窗載入的所有的頁面都是共享乙個 window.name。
通常做法是用乙個隱藏的iframe 去載入乙個同域的**檔案:proxy.html,在**檔案中設定window.name,再動態替換iframe的src為外域的url,這樣就可以通過window.name傳遞有效資訊。
因為proxy.html 和 真實需要跳轉的外域 url 都是在同乙個iframe下,window物件是同乙個。
如果需要回傳資料給父視窗,就反著來。可以先用iframe開啟外域的url,在外域的檔案中設定 window.name後,再跳轉到 同域的 proxy.html。父視窗這時再獲取
缺點:需要乙個**檔案 proxy.html。window.name 只能設定字串型別。
postmessage原理:說不清, 此乃瀏覽器自帶 api。具體用法就不介紹了。
缺點:接收方需要監聽 message 事件。
websocket原理:webscoket採用的是 ws:// 或 wss:// 協議,非 http 協議。協議不實行同源政策,只要伺服器支援,就可以通過它進行跨源通訊,需要在服務端設定白名單。
缺點:說不清
cors原理:說不清
缺點:對於複雜請求,如非get,或資料格式為json的請求, 會觸發兩次請求。一次為 options 預檢請求,第二次才是正式請求。
伺服器**跨域原理:了解一點 — 利用後端訪問介面不存在跨域的特點。
缺點:說不清
日常前/後端配合開發中,個人覺得配置好cors即可。
前端解決跨域問題總結
其實一般情況下,都是由後端解決跨域問題,因為後端處理跨域比前端 更加方便,而且更加安全,前端處理跨域安全性不高,資料容易被劫持,但是當後端實在沒辦法解決的時候就需要我們前端處理了 什麼叫做跨域 乙個域下的文件或者指令碼檢視請求另乙個域下的資源叫做跨域 如何判斷跨域 同源策略 協議,網域名稱,埠三者相...
cookie跨域問題 跨域登入
cookie跨域時修改不成功,需要在刪除 或者修改時 設定domain值與存入的domain一致,跨域修改cookie不會成功。例如 login.abc.com login工程 www.abc.com abc工程 www.abc.com login.html呼叫login工程的登陸介面 login工...
跨域問題以及攜帶token問題總結
這裡邊注意文件中給的語法,有的可以使用 但是有的需要寫出每乙個header 我的專案登入時後台會給前端的response data中返回乙個token和refresh token。除了登陸操作,所有的ajax操作都需要帶著token這個請求頭去訪問,如果token過期了,通過refresh toke...