国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

同源策略及跨域訪問

tomato / 3237人閱讀

摘要:同源策略及跨域訪問同源策略同源策略約束了兩個域之間資源的加載方式,是一個很重要的安全機制用來隔離那些有潛在安全隱患的文檔。

同源策略及跨域訪問 同源策略

同源策略(Same-origin policy)約束了兩個域之間資源的加載方式,是一個很重要的安全機制用來隔離那些有潛在安全隱患的文檔。

何為源(orgin)

一個源由一個URL的協議(protocol)、主機(host)和端口(port)進行定義。如果兩個頁面擁有相同的協議、主機和端口一致的話,我們就可以稱它們為同源。下面的表格比較了不同的URL跟http://store.company.com/dir/page.html這個URL的同源情況:

URL 是否同源 理由
http://store.company.com/dir2...
http://store.company.com/dir/...
https://store.company.com/sec... 協議不同
http://store.company.com:81/d... 端口不同
http://news.company.com/dir/o... 主機不同
跨域訪問

同源策略控制了兩個源之間的交互,例如你使用XMLHttpRequest發起一個請求,或者使用元素加載一張圖片,就會產生兩個源之間的交互。而當兩個源不相同時,有些交互會被允許,而有些則不被允許。而不允許的情況,就是我們常說的跨域訪問問題。那什么情況下不同源的交互會被允許,什么情況下又不被允許呢?大致可以分為如下的情況:

鏈接、跳轉和表單提交這些在跨域的情況下都是被允許的。例如調用支付寶接口進行支付就是典型的跨域表單提交的場景,這種跨域的調用是被允許的。但是這個很容易被利用來進行CSRF攻擊,所以我們的表單提交需要做好這方面的防護。

跨域的資源內嵌是被允許的。下面是一些資源內容的例子:

使用加載Javascript。只有同源的腳本在語法錯誤時會顯示錯誤信息。

使用加載CSS。跨源的CSS文件要求使用正確的Content-Type 響應頭。

使用加載圖片。

使用加載媒體文件。

使用 加載插件。

使用 @font-face加載字體。有些瀏覽器允許加載跨域的字體,有些則不允許。

使用

然后在http://sub.example.com/iframe.html頁面對父頁面的背景色進行修改:




    ......


    

由于兩個頁面不同源,所以子頁面對父頁面的操作被禁止,例如在Firefox上你會看到以下的報錯:

Error: Permission denied to access property "document"

不同源之間的XMLHttpRequest調用(也就是我們常說ajax調用)是不被允許的,這個也是我們最常遇到的跨域訪問場景。例如我們在http://example.com/index.html頁面進行如下的ajax調用:

var xhr = new XMLHttpRequest();
var url = "http://otherexample.com/api/get-data";
   
xhr.open("GET", url, true);
xhr.onreadystatechange = handler;
xhr.send();

在Firefox下會報如下錯誤:

已攔截跨源請求:同源策略禁止讀取位于 http://otherexample.com/api/get-data 的遠程資源。(原因:CORS 頭缺少 "Access-Control-Allow-Origin")。
跨域訪問的解決方案

修改源

一個頁面的源是可以修改的,修改的方法很簡單,就是通過Javascript腳本設置document.domain的值。舉個例子,我們在頁面http://store.company.com/dir/other.html執行下面的代碼:

document.domain = "company.com";

那么這個頁面的域將會由store.company.com變成company.com,后面在判斷是否同源的時候,主機將會使用company.com這個值,而不是store.company.com

那是不是修改域后就能跟同域的頁面進行交互呢。答案是否定的。例如,如果你在頁面中通過iframe嵌入http://company.com/dir/page.html這個頁面,然后通過javascript去跟這個頁面交互,你會發現瀏覽器會報錯,就跟我們之前那個例子一樣。按照上面的源的定義,這時候兩個頁面應該是同源的,為什么呢?因為修改document.domain會導致端口號被設為null。所以另外一個頁面也需要把document.domain修改為相同的值,這樣兩個頁面的主機和端口就一致了,可以進行互相的訪問了。

既然源可以修改,那么是不是就解決了我們的跨域問題呢?明顯沒這么簡單。首先,這種方法是有很大限制條件的,document.domain這個值只能修改為這個頁面的當前域或者當前域的超級域。所以,這個方法只能解決同一超級域下的頁面跨域問題。其次,它的使用場景也很有限,因為它需要頁面執行Javascript腳本,所以也就是說一般只能應用于頁面跟頁面的交互,例如訪問ifame頁面或者window.open打開的頁面等等。所以如果你想用來解決ajax之類的跨域調用,這個方法就無能為力了。

使用代理

使用代理也是解決跨域訪問的一個方法。上面修改document.domain的方法只能用來訪問子域名的頁面,無法訪問不同域的頁面,而使用代理則沒有這個問題。

例如我們有一個頁面http://example.com/,需要訪問http://otherexample.com/這個頁面,我們不直接對這個頁面進行訪問,而是通過請求另外一個同源的頁面,這個頁面在后端通過代理服務器把請求轉發到http://otherexample.com/,獲取數據并返回給客戶端。

另外,這個方法同樣可以用于解決ajax的跨域訪問問題。

JSONP

JSONP也被經常用來解決ajax的跨域調用問題。JSONP請求并不是通過XMLHttpRequest發起,而是使用

然后接口獲取到callback函數名后,把原來返回的數據作為函數的參數,最終返回如下的Javascript:

myFunction({"id": "123", "name": "Captain Jack Sparrow"});

然后myFunction就會執行,達到了調用的目的。

這個方法在大多數情況下都很有用,但是它也有它的局限。一是它需要后端的配合,因為后端的接口需要根據約定的參數獲取回調函數名,然后跟返回數據進行拼接,最后進行響應。二是它只能進行異步的調用,因為它的原理是通過動態生成

閱讀需要支付1元查看
<