為什麼只有瀏覽器(或JS)是有所謂的同源策略?

而客戶端(Android、ios)好像都沒有聽說過類似的限制?難道開發一個app可以隨便調用web介面?


假設沒有同源限制,A網站的API可以被任何來源的AJAX請求訪問,包括獲取用戶的隱私信息,只看用戶有沒有登錄,現在有個壞人做了一個網站B,壞人在B網頁中用AJAX訪問A網站的API,如果一個用戶訪問B之前已經登錄了A,那這個請求包含A網站的cookie信息,也就會被A網站認為用戶已經登錄,這樣用戶在A網站的隱私信息就泄露給了控制B網站的壞人。

不過,如果A網站覺得一些信息跨站訪問也無所謂,那就可以通過jsonp或者CORS規則暴露,關鍵是A網站主動允許不同源的請求。


因為瀏覽器是公共環境,App 是私有環境。

公共環境的基本規則就是不要把手伸進別人的口袋。

私有環境就沒那麼多限制了,你把你手伸進你女朋友衣服里都沒人管。

哦,我忘了你沒有女朋友。


這是因為瀏覽器向一個域發起請求時總是會帶上這個域及其父域的cookies。於是別有用心的人就可以誘騙你進入一個陌生頁面,並向一些你可能登錄過的網站發請求,盜取你的信息或做一些敏感操作。

其他你可能感興趣的補充:

  • 同域策略只阻止你讀取AJAX返回的內容,實際上請求依然發送到了伺服器。
  • fetch API可以在發起請求時不攜帶cookies;img和script等標籤在現代瀏覽器中也可以。
  • cors之所以在複雜請求時要發起兩個請求,也是為了儘可能地防止不支持cors的伺服器無意中認可了cors請求,出現和跨域一樣的安全問題。
  • JSONP雖然能夠繞過同源策略,但其實和普通的跨域請求一樣危險,知名網站有時也會因此出現安全問題。
  • canvas雖然可以繪製跨域來源的圖片,但如果這張圖片在請求時帶上了cookies,那麼canvas當中的內容就無法再通過API導出了,這也是為了防止用戶的隱私被盜取。
  • 雖然不寫埠號在http協議時默認80埠,但如果在不寫埠的域上,請求顯式寫明80埠的域,則這個請求也可能是跨域的,具體情況需要看瀏覽器實現;同理https和443也是一樣的。
  • script標籤在跨域時onerror可能會取不到任何異常詳情,這同樣是為了保護用戶信息安全。
  • WebSocket在連接建立時,瀏覽器發起的第一個握手請求實際為GET請求,這個請求可以跨域,而且這個請求會自動帶上cookies。但在目前瀏覽器的實現中,開發者的代碼無法拿到請求的返回內容。如果在https頁面嘗試建立非wss的連接,則這個握手請求會被瀏覽器阻斷。對於不支持WebSocket協議的伺服器,請求的返回會缺少一些協議規定的信息,此時瀏覽器會終止WebSocket的建立。細節可以參考相應的RFC。
  • HTTP/2中,攜帶cookies的請求和不攜帶cookies的請求在一些瀏覽器中會被拆分成到不同的連接當中,這一行為會導致一些你認為已經進入客戶端cache的資源出現重新下載的情況。
  • 跨域還影響其他很多API,可以自行探索。


同源策略是 W3C 規範里的,瀏覽器廠商也是這麼實現的,和JS語言本身沒太大關係。

另外也存在各種跨域的方案,比如:JSONP這種非官方的跨域方案。

理論上Android和iOS是可以調用跨域Web介面,只要是有足夠的許可權。

參考:

瀏覽器的同源策略


主要是因為同源策略是W3C的標準,瀏覽器內核對HTML,CSS,JS的處理都是基於W3C標準的,而Android和iOS的客戶端是APP,不需要遵守W3C標準,所以就不受同源策略的約束,但系統中的webkit組件還是會遵守這個標準。

不過我覺得在安全方面,同源策略已經是最基本的了,應該納入常識範疇,現在需要關注https。


瀏覽器為了保護用戶的數據安全,儘可能阻止跨域攻擊,所以要儘可能限制危險的跨域手段

因為如果不這麼做的話,用戶真的有可能僅僅因為手滑點了不該點的鏈接而發生非常不好的事情的,然後用戶就要抱怨瀏覽器不安全,所以瀏覽器有動力解決這個問題。


首先,瀏覽器與服務端之間的交互是通過HTTP請求來進行的,你可以用postman之類的程序,模擬一個最簡單的HTTP請求,你會發現跨域限制並沒有出現。

很明顯,同源策略是瀏覽器的內部實現。更具體地說,其實是瀏覽器內部的XMLHttpRequest對象限定了同源策略,與JS無關。

為什麼瀏覽器需要同源策略呢?主要是為了防止來源於其他網站的JavaScript,獲取到當前網站的資源(例如Cookie)。

假設沒有同源策略的話,當你上某一個小黃網的時候,這個小黃網可能就會內嵌了一段AJAX,偽裝成你來訪問其他的網站。這樣子無疑是很不安全的(沒人敢上小黃網了)。

那麼為什麼APP之類的就不需要同源策略呢?因為同一個APP內的請求,都是你自己寫的,除非你這個APP被修改過了或者APP內部允許用戶主動去控制HTTP請求的內容,不然一般來說沒有加上同源策略的必要(當然你要加上也是可以的,例如當你要做的APP就是一個手機瀏覽器的情況下,你就得記得要去做同源策略的約束了)。

對於多個APP之間,其實也是要去限制其他的APP獲取當前APP的資源、或者修改當前APP的內容的。但是,這個就不是由APP開發者來操心的了,這就是要由操作系統來做訪問許可權的控制了。


因為這個是公共設備呀,共用的當然要分許可權,否則你可以拿別人的東西。


打個比方吧,瀏覽器就相當於一個汽車站的候車廳,只要買了票都可以進去候車,為了防止一些無知的旅客拿著自己的車票(cookie)亂上車,所以上車前乘務員需要對乘客進行檢票(是否是符合同源策略),車站不檢票(瀏覽器沒有同源策略)的後果可想而知;但是如果你乘坐的是私家車(Android、iOS、Server)那還檢什麼票直接上車好了。


開發app是可以調不同web的介面。但是你沒法繞過許可權認證啊。除非你的app跳到別的web頁去登陸。那樣我感覺你只是做了一個不安全的瀏覽器。


為了安全 瀏覽器是公用的 app是公司自家的


推薦閱讀:

Chrome 真的很費電嗎?
豆瓣的回應按鈕為何不加以美化,而直接使用瀏覽器默認樣式?
Chrome 瀏覽器的名字有什麼來歷?
360 瀏覽器佔有率從 2012 年 7 月的 22.53% 驟降到 9 月的 2.44%,原因是什麼?
從瀏覽器的網頁上複製文字與圖片以後在word粘帖不顯示圖片?為什麼?

TAG:JavaScript | 網頁瀏覽器 | 移動開發 |