Access-Control-Allow-Origin 頭部如何工作?


在本教程中,我們將學習訪問控制如何允許源標頭工作。

Access-Control-Allow-Origin 是 CORS 的一個頭部。使用 CORS 或跨源資源共享,瀏覽器可以允許託管在源 A 上的網站請求源 B 上的資源。

源是埠、主機名和方案的混合,例如 http://tutorialspoint.example.com:5000/,而不僅僅是主機名。

以下是如何將其付諸實踐的示例 -

  • 我想從源 B(即 http://yoursite.com)和源 A:https://tutorialspoint.tw 獲取資源。

  • 瀏覽器將拒絕我的請求並阻止我訪問 yoursite.com 的資源以維護您的安全。

  • 您的源 B 必須通知瀏覽器允許源 A 訪問您的資源,以接受我從您的源接收資源。

瀏覽器允許源共享資源是由於 CORS。

源之間資源共享的關鍵標頭是 Access-Control-Allow-Origin,儘管還有其他一些標頭。瀏覽器透過這些標頭被告知哪些源被允許向此伺服器傳送請求。

誰需要配置 Access-Control-Allow-Origin?

請考慮以下示例以確定誰應該設定此標頭:您正在檢視一個可以檢視和收聽歌曲的網站。該網站在後臺偷偷嘗試連線到您的銀行。

因此,銀行必須將 Access-Control-Allow-Origin 標頭設定為響應的一部分,以保護其資源。請記住,此標頭必須由負責提供資源的源設定。

什麼是 CORS?

CORS 或跨源資源共享是一種方法,它透過使用額外的 HTTP 標頭告訴瀏覽器可以使用其他源。

用於訪問 URL 的協議、主機和埠標識 Web 內容片段的源。如果兩個專案的方案、主機和埠相同,則它們可以共享相同的源。

當告訴瀏覽器接受來自任何源的程式碼以訪問資源時,響應應為 -

Access-Control-Allow-Origin: *

非簡單請求

事件的網路級別可能比之前描述的稍微複雜一些。為了確定伺服器是否會接受“非簡單”請求,瀏覽器首先發出一個無資料的“預檢”OPTIONS 請求。當以下任一(或兩者)情況發生時,請求不是簡單的

  • 使用 GET 或 POST 之外的 HTTP 動詞(例如,PUT、DELETE)

  • 使用複雜的請求標頭(唯一的特定請求標頭是 -

Accept、Accept-Language、Content-Language 和 Content-Type(只有當值為 text/plain、application/x-www-form-url 編碼或 multipart/form-data 時,這才簡單)。如果伺服器使用與非簡單動詞和非簡單標頭匹配的響應標頭(對於非簡單標頭使用 Access-Control-Allow-Headers,對於非簡單動詞使用 Access-Control-Allow-Methods)來響應 OPTIONS 預檢,則瀏覽器將傳送請求。如果站點 A 想要傳送對 /somePage 的 PUT 請求,並且 Content-Type 值為非簡單的 application/json,則瀏覽器將首先執行預檢請求 -

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

需要注意的是,瀏覽器會自動新增 Access-Control-Request-Method 和 Access-Control-Request-Headers;您無需新增這些。例如,此 OPTIONS 預檢的成功響應標頭如下 -

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

傳送提案時的行為與處理簡單請求的方式相同(一旦預檢完成)。換句話說,如果非簡單請求的預檢成功,則它將被視為簡單請求(即,伺服器仍然必須再次傳送 Access-Control-Allow-Origin 以進行實際響應)。

The browsers send the actual request:
PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json
{ "myRequestContent": "JSON is so great" }

並且與簡單請求完全一樣,伺服器會回覆 Access-Control-Allow-Origin -

Access-Control-Allow-Origin: http://siteA.com

示例

在下面的示例中,我們建立了一個在 localhost 的埠 5000 上執行的伺服器。在此應用程式中,我們將 Access-Control-Allow-Origin 標頭設定為 tutorialspoint。如果我們從 tutorialspoint 與伺服器通訊,則它將正常工作。但是,如果我們嘗試與任何其他域通訊,它將丟擲錯誤。我們無法從除 tutorialspoint.com 之外的其他域傳送任何 get 或 post 請求。

const express = require("express");
const app = express();
// Access-Control-Allow-Origin
app.use((req, res, next) => {
   res.setHeader("Access-Control-Allow-Origin", "https://tutorialspoint.tw");
   res.header(
      "Access-Control-Allow-Headers",
      "Origin, X-Requested-With, Content-Type, Accept"
   );
   next();
});
app.get("/view", (req, res) => {
   res.send("Welcome to Tutorialspoint!");
});
app.listen(5000, () => console.log('Listening on port 5000'));

嘗試從 localhost:3000/ 向 localhost:5000/ 傳送 get 請求。

fetch('https://:5000/view')
.then(response => console.log(response));

輸出


將標頭更改為以下內容以解決此問題 -

res.setHeader("Access-Control-Allow-Origin", "*");

更新於: 2022-12-06

3K+ 瀏覽量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.