跨域資源共享(CORS)是什麼?

Learn_anything發表於2021-11-24
一、CORS 是什麼?

出於安全原因,瀏覽器會限制指令碼發起的跨域 HTTP 請求,除非伺服器同意訪問。譬如伺服器對預檢請求的響應 Header 中有 Access-Control-Allow-Origin: *,那麼跨域請求即可正確訪問。


二、危害舉例

如果惡意網頁中含有這樣的指令碼程式碼 fetch("example.com"),而你已經登入了 example.com 網站還沒有退出,如果此時沒有 CORS 限制,那麼惡意網頁中的指令碼程式碼就會順利透過伺服器執行,您的大量個人資訊會被洩露。


三、預檢請求是什麼?

為了避免跨域請求對伺服器的資料產生不可知的影響,瀏覽器會用 OPTIONS 方法,先傳送一個預檢請求(preflight request),待伺服器確認可以訪問後,再傳送實際請求。

下面這個 POST 請求,就會先傳送預見請求,可以在控制檯的網路連線中檢視具體連線和資訊。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';

function callOtherDomain() {
    if (invocation) {
        invocation.open('POST', url, true);
        invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
        invocation.setRequestHeader('Content-Type', 'application/xml');
        invocation.onreadystatechange = handler;
        invocation.send(body);
    }
}

四、怎麼用 CORS?

CORS 的工作主要在服務端,透過返回不同的 Header 來告知請求者,是否可以訪問?下面兩個部分列出了 CORS 所有用到的 Header 及其含義。

1、其他使用場景

CORS 可以配合 token 來防止 CSRF 攻擊。詳情,看這裡!


五、客戶端跨域請求

跨域請求用到如下 Header ,無須手動設定,瀏覽器會自動設定。

1、origin
  • 預檢請求和實際請求中的源站名稱,不包含任何路徑資訊,只是伺服器名稱。

    Origin: <origin>

2、Access-Control-Request-Method
  • 用於預檢請求,告訴伺服器,實際請求 使用什麼方法:post、get 等。

    Access-Control-Request-Method: <method>

3、Access-Control-Request-Headers
  • 用於預檢請求,告訴伺服器,將實際請求所攜帶的首部欄位。

    Access-Control-Request-Headers: <field-name>[, <field-name>]*

六、伺服器響應跨域請求
1、Access-Control-Allow-Origin
  • 用於響應預檢請求,表示允許該資源的外域 URI

    // 允許所有
    Access-Control-Allow-Origin: *
    
    // 只允許 http://mozilla.com
    Access-Control-Allow-Origin: http://mozilla.com

2、Access-Control-Expose-Headers
  • 對於自定義的 Header ,必須這裡設定,客戶端才能正常訪問

    Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
3、Access-Control-Max-Age
  • 設定預檢請求的結果能夠被快取多少秒?

    Access-Control-Max-Age: <delta-seconds>
4、Access-Control-Allow-Credentials
  • 當跨域請求中設定了 credentials=true,但服務端響應中沒有 Access-Control-Allow-Credentials: true,那麼瀏覽器是不會把伺服器返回的資料發回給請求者。

    Access-Control-Allow-Credentials: true
5、Access-Control-Allow-Methods
  • 用於響應預檢請求,指明實際請求所允許使用的 HTTP 方法

    Access-Control-Allow-Methods: <method>[, <method>]*
6、Access-Control-Allow-Headers
  • 用於響應預檢請求,指明實際請求中允許攜帶的 Header

    Access-Control-Allow-Headers: <field-name>[, <field-name>]*

七、參考文件

相關文章