03.05 什麼是跨域,跨域的實現方式有哪些?

用戶65981909


查了一些資料,再結合我之前的瞭解,給大家介紹一下,如果有說的不對的地方,請大家留言指正。


什麼是跨域

瀏覽器有一個毛病(策略):請求url的協議、域名、端口必須相同,才允許訪問(通信),否則就不允許訪問,是跨域。

https(協議)://www.wukong.com(域名和端口)/index.html


比如:

https://www.wukong.com/index.html

http://www.wukong.com/index.html

這樣就不允許通信,因為協議不同。


完整的舉個例子:

你有服務器A和服務器B,服務器A上存著CSS和JS腳本,服務器B上存著HTML,HTML頁面上的CSS和JS都是鏈接的服務器A上面的。

然後用瀏覽器打開服務器B上面的xxx.html,頁面打開後可以正常渲染出樣式,可以運行JS腳本,這樣就是跨域名,跨端口,跨協議

如何解決跨域

  • JSONP:利用了script標籤不受同源策略的限制,通過script加載服務器A的資源。

  • Proxy代理:使用服務器接口做代理,因為同源策略之針對瀏覽器。

  • CORS:跨域資源共享,這個就是瀏覽器後悔了,出了一個跨域訪問機制(XMLHttpRequest),低版本IE不支持。

  • Postmessage:HTML5新增的跨域機制。

  • Nginx反向代理:相當於Proxy代理。


希望我的回答可以幫助到你!


會點代碼的大叔


在介紹跨域之前,我們需要先了解一下同源策略。那麼什麼是瀏覽器的同源策略呢?

同源

同源是指協議,域名,端口完全相同。

比如

  • http://www.example.com/index.do

  • http://www.example.com/login.do

而下面的任意一種都是不同源的。

協議不同

  • http://www.example.com/index.do

  • https://www.example.com/login.do

域名不同

  • https://www.example.com/index.do

  • https://subdomain.example.com/login.do

  • https://www.test.com/login.do

端口不同

  • http://www.example.com:80/index.do

  • http://www.example.com:8080/login.do

同源策略

同源策略(SOP,Same origin policy)是指作為瀏覽器最基本安全功能的一種約定,它對以下請求進行限制來降低受到XSS、CSFR等攻擊的風險。

  1. 瀏覽器的存儲

  2. 瀏覽器DOM對象和腳本

  3. AJAX請求


那麼現在可以來認識一下什麼是跨域了。

跨域

廣義上的跨域是指一個域下的資源去請求另一個非同源域的資源,而狹義上的跨域是指同源策略限制的這一類請求。

解決跨域問題的常用手段:

  • 跨域資源共享(CORS)

服務器端指定請求頭中的Access-Control-Allow-Origin字段即可。

'Access-Control-Allow-Origin': '*' // *代表所有,在實際開發中,應當遵循最小授權的原則來指定域名

  • 代理服務器

同源策略是針對瀏覽器的,對於服務器是沒有限制的,所以只需要製作一個代理服務器,然後將原來的請求轉發到目標服務器即可。

  • nginx反向代理

靜態代理

在靜態代理服務器中加入請求頭信息,和第一種相似

location / {
add_header Access-Control-Allow-Origin *;
}

代理服務器作為中間跳板

和第二種相似

  • jsonp方式

js,html,css對應的標籤是允許跨域加載靜態資源的,但是jsonp只支持get方式。


還有很多方式可以解決跨域問題,你還有哪些葵花寶典,發來欣賞一下可好?


飛昇的碼農


Web場景中包含了腳本執行功能的用戶代理(典型的是瀏覽器),對跨域訪問實施了安全限制(遵循同源策略),導致我們在開發中碰到跨域訪問時需要使用特定機制來實現。

跨域的域

這裡的域,不是單純的域名。IETF的RFC6454標準(2011年12月正式發佈)說明了源(Origin)的概念。源是一組URI的集合,而這一組URI的特徵是完全符合一個三元組(uri-scheme,uri-host,uri-port)。我們所說的跨域訪問,實際上是跨源訪問。後續回答中的描述中域和源可能混用。

依據三元組很容易劃分哪些URI同源,哪些不同源。下面兩張出自RFC6454的示例列表(第一張3個同源,第二張都不同源):

協議標準將scheme、host、port都作為源的分組條件,是基於以下考慮的:

1、不同的協議一般會實施不同的安全策略,比如https通過TSL加密傳輸數據提高安全性。

2、父子域名配合端口,在稍大的平臺中其實都是分開部署(這裡自然還含架構設計等),且有不同安全級別的要求。比如京東登錄使用的是passport.jd.com子域名,很多子系統的登錄入口都在這裡。

IE比較調皮,未將端口加入分組要素,也就是不同端口並不跨源(第二張圖片前兩個URI在IE在就是同源),同時對於域也有自己安全區域的一套機制。

跨域的安全問題

Web領域的用戶代理,實際包括瀏覽器、僅實現HTTP功能的編程組件,爬蟲工具等。瀏覽器需要渲染界面(html、css)、執行腳本(js),同時瀏覽器是一個公共環境,我們可以用它瀏覽來自全世界Web服務器提供的資源信息。因為有了腳本執行能力(包括js以及各種插件擴展),如果不加限制自然會引發了諸多的安全問題。跨域方面的安全問題主要包括跨站腳本(XXS)、跨站點請求偽造(CSRF)等。下圖示owasp發佈的2017年10大威脅,詳細信息可以上owasp官網查看。

跨域的安全問題主要是基於同源策略(Same-origin policy)來限制。

簡單來說同源策略主要保護是某一個源相關的js對象以及其它可訪問資源(比如cookie、本地存儲等)。比如:很多服務器基於 cookie信息來發布敏感信息或採取狀態改變操作。必須在客戶端維護由不相關站點提供的內容之間的嚴格分離,以防止數據機密性或完整性的丟失。

跨域訪問策略

用戶代理對跨源訪問會做諸多限制,但同時也會提供跨源訪問的機制。服務端也會有限制客戶端跨域訪問的需求,典型比如的盜鏈問題。所以跨域訪問需要清楚服務端和客戶端各自的限制和需求。我主要分下面兩個場景來描述可用策略。

跨源本地訪問

因為frame的存在,我們可以在同一頁面包含不同源的資源;我們也可以在新窗口中打開不同源的頁面。

我們可以通過跨文檔消息來實現交互:通過window對象異步調用postMessage方法,在另一個窗口觸發onmessage事件。window對象可以通過多種方式獲取到引用,比如iframe的contentWindow、window.open返回的window對象、或者在window.frames中查找。

跨源訪問不同服務器資源

可用策略多種多樣,我把他們歸為以下幾類:

  • 利用漏洞:如Jsonp,這個和XXS有異曲同工之妙。瀏覽器下載並執行非同源js是必要的,但是存在安全隱患,所以不要亂引用三方腳本。

  • 插件擴展:通過flash,silverlight等插件擴展避過瀏覽器的直接限制,充當客戶端代理層。

  • 補充協議:跨域資源共享(CORS)目前由WHATWG維護。本質上是客戶端和服務端協商機制。詳情可參考fetch文檔或者MDN文檔說明。
  • 換協議:Websocket不使用同源策略,但瀏覽器提供Origin頭,服務端可以維護白名單來進行跨域限制。
  • 服務端代理:通過nginx之類的代理服務器將不同源的信息轉化為同源信息,客戶端就不存在跨域問題了。也可以自己實現一個代理組件,這裡依賴的就是HTTP組件並未提供嚴苛的同源策略實現,你甚至可以根據需要修改Origin頭來欺騙對方服務器。
  • 父子域名:可通過更改document.domain來臨時放寬同源限制。

如果你思維夠抽象,你會發現跨域訪問和IPC機制很相似,只要你想得透徹,方式方法很多。

Tips:MDN是個不錯的Web開發參考網站,由mozilla維護,可用來做知識點補充(深度不太夠,但是包含範圍很廣)和API參考。IE的官方文檔關於API的參考也是重定向到這裡,其實想想也挺搞笑的,實現走非主流路線,文檔倒是走到一起了。

總結

跨域背後是安全性問題,包含有還有非常多的規範和實現細節,比如安全上下文、源的繼承等等。與跨域訪問需求相對的,我們有時還需要非常嚴格的跨域訪問限制,防止各種安全問題出現。

跨域訪問需求很廣泛,以後可能還會出更多的規範放寬同源限制,原則應該都是需要客戶端和服務端預先了解到風險並確認風險,跟APP應用開發的授權類似。不過在安全性和便利性之間的取捨不是那麼容易的。


個人手敲,歡迎批評指正。


遷徙de麻雀


關於,跨域問題,我剛寫了一篇文章,現在就貼過來供給參考

大家有時經常問什麼是跨域問題,這個問題並不是一句話能回答的,因為我也不知道你說的是哪一種性質的跨域,比如說,你說的是不同域名的session共享呢?還是說ajax跨域問題呢。不管是哪種的跨域,我今天的文章中都給它列出來,並附上具體的操作方法,供大家借鑑,一起學習交流。

先說session共享的跨域問題,一個域名下都會保持一份會話,跨域就是說從一個域名到另一個域名這個會話還能繼續保持,很常見的就是在一個網站跳到另一個網站還是繼續保持登錄狀態,一般情況下從一個域名下跳到另一個域名下,登錄狀態是會丟失的,如果說沒有丟失,那麼就是進行了跨域處理。

圖片來之互聯網

關於跨域處理有兩個級別的處理:

1.兩個不同的二級域名session共享

這種級別的處理做個簡單的設置就可以了,一句代碼就可以做到會話保持,我以php為例,假如說你是是個電商網站,一個是母嬰頻道,一個是數碼頻道,他們是兩個不同的二級域名,比如一個是muying.yourdomain.com,一個是dianzi.yourdomain.com,如果不做任何處理的話,從muying.yourdomain.com跳轉到dianzi.yourdomain.com登錄狀態是沒法保持的,要想做到兩個二級域名的跨域就可以去修改php.ini的配置,修改改配置項session.cookie_domain,如果覺得修改配置項嫌麻煩的話,也可以修改php代碼,在自己的php框架裡處理session的地方加上這麼一句就可以了

ini_set("session.cookie_domain\


分享到:


相關文章: