CORS 是什麼?前後端工程師必知的跨網域資源共享

更新 發佈閱讀 37 分鐘
CORS error message

CORS error message

前言

原本在處理前端 Next.js 跟後端 Node.js 之間的 fetch 資料傳輸,以為會碰到 CORS 的問題,但是後來發現在伺服器之間的 API http 通訊之間並不會觸發 CORS 限制,因為 CORS 是瀏覽器保護使用者的一種安全機制,如果這種專門給 Server 使用的 API 如果需要安全檢查,就要用 Server-to-Server API 專用的安全檢查方式,如 API Key 、 Shared Secret + HMAC 、 JWT 驗證 、 OAuth 2.0 Client Credentials(常見於企業級或第三方服務整合)等等方式。不過這也表示, 只要 API 本身沒有實作任何身分驗證或流量控管機制 ,即使 API 它是「設計給瀏覽器使用」且已正確設定 CORS ,但是只要它沒有實作任何「請求來源驗證、身分驗證或流量控管」機制,任何能發送 HTTP Request 的程式(爬蟲、bot、惡意腳本)都可以直接呼叫它,並進行攻擊。

從伺服器角度來看,HTTP Request 並不區分是否來自瀏覽器,因此僅依賴 CORS 並不能視為 API 安全防護。

簡介

什麼是同源政策(Same-Origin Policy, SOP)?

因為瀏覽器有同源政策(SOP, Same-Origin Policy)的緣故,其原由已經在 前一篇文章詳述了 ,所以這裡並不會再詳述細節。

所以當瀏覽器要存取跨網頁網域資源時,就需要用到跨來源資源共享 CORS(Cross-Origin Resource Sharing)機制。

瀏覽器會將來源(Origin)定義為三個組合:

  • 協定 (protocol), ex: http, https
  • 網域 (domain), ex: example.com
  • 連接埠 (port), ex: 80, 443

只要以上三者其中一項不同,就會被瀏覽器視為不同來源 (cross-origin) 。

在 SOP 的限制下, 瀏覽器預設禁止網頁直接讀取不同來源的資源內容 ,以防止惡意網站竊取使用者資料。

為什麼需要 CORS ?

然而,並非所有跨源存取都是惡意行為,例如:

然而,並非所有跨源存取都是惡意行為,例如:

  • 前端呼叫自家後端 API
  • 使用 CDN、第三方 API
  • 前後端分離架構(SPA + API)

因此,瀏覽器提供了 **CORS(Cross-Origin Resource Sharing)** 這套機制,讓後端伺服器可以「明確告訴瀏覽器」:

那些來源是可以合法存取這些資源

CORS 的歷史背景簡介

在 CORS 出現之前,開發者曾使用過一種替代方案: JSONP(JSON with Padding)

JSONP 的原理是透過 <script> 標籤載入遠端 JavaScript,藉此繞過同源政策限制。但由於它本質上是執行遠端程式碼,因此在安全性與可控性上存在風險,也容易成為 XSS 攻擊的載體。

JSONP 只能使用 GET,因為 <script src="..."> 本質上無法攜帶 request body,也無法自訂 HTTP method,所以使用上也比較複雜。

隨著 Web 應用日益複雜,以及 CORS 的出現,這種方式逐漸被淘汰。

CORS 的相關概念在 2000 年代中期開始被提出,並於 2010 年前後由 W3C 整理為正式規範,之後逐步被主流瀏覽器全面支援,成為現代 Web 開發的標準做法。

CORS 的角色分工

CORS 的限制與判斷,實際上是由瀏覽器執行的。

前端瀏覽器負責依 CORS 規範判斷請求流程

瀏覽器會根據 HTTP Request 內容判斷是否為同源,如果為非同源就會走 CORS 流程,之後瀏覽器會根據該 Request 內容是否符合 Simple Request 的條件,不符合則會在正式發送 Request 以前先向後端伺服器發送 Preflight (OPTIONS) Request ,以判斷後端伺服器是否接受該 CORS Request

是否允許該跨來源請求攜帶 credential (如 cookies、Authorization header) ,以及是否允許 JavaScript 存取回傳的 response。

後端伺服器的 HTTP Response 是否有做 Preflight(OPTIONS) HTTP Response Header 處理,會影響到瀏覽器收到 Response 後判斷該 Response 是否為合法的 CORS Response , JavaScript 是否可以處理 HTTP Response 跟 Cookies 內容。

後端伺服器負責角色

後端伺服器的腳色,僅僅只是在 HTTP Response 中回傳 CORS Header處理 CORS Preflight

瀏覽器收到 Response 後,才會根據這些 Header 決定:

  • 是否允許 JavaScript 讀取 response
  • 是否要在 console 顯示 CORS error

以下以 Node.js express 先不使用 cors 這個套件處理,純手寫的方式,展示基本的流程,尚未觸及更複雜的 credential ,並以註解說明各段程式碼在後端的 CORS 處理的作用是什麼,以清楚說明後端對於 CORS 處理的細節。

不過實務上並不建議用純手寫的方式來處理後端的 CORS ,建議以專用套件來處理 CORS 流程。純手寫的除了程式碼攏長,處理各個功能流程邏輯複雜,還容易一不小心忽略必要的 Header 處理,導致到時要 debug 很久。

import express from "express";

const app = express();
const port = 2000;

// CORS middleware
// 所有的 http response 都會帶有這些 CORS 相關的 header
app.use((req, res, next) => {
  // 後端回傳 response header CORS 允許的網域,]
  //  * 代表所有網域,可以指定一個網域,如: https://example.com ,如需要多個白名單,在後面 CORS 套件會詳述方法
  // 不過如果是要用 credentials (cookies) 要指定明確的網域,不能用 *
  // 除非是對外自由開放的 API ,不然實務上並不建議使用 * ,通常會搭配白名單動態判斷 Origin 來源是否為允許的來源。
  res.setHeader("Access-Control-Allow-Origin", "*");

  // 後端告訴瀏覽器:允許的 HTTP 方法
  res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");

  // 這段是在處理非 simple request 時候,
  // 會先送 Preflight(OPTIONS)詢問是否允許使用這些 HTTP header
  // 瀏覽器會比對 Access-Control-Request-Headers
  // 與後端回傳的 Access-Control-Allow-Headers 是否相符
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

  // 如果是 CORS Preflight (OPTIONS),便會在此結束,並回傳帶有以上程式碼後端所給的 http response header
  // 給瀏覽器檢查後端回傳的規則,讓瀏覽器決定是否要發出真正的 request
  // 此時不進入任何 API 邏輯,直接回成功狀態即可
  // OPTIONS 沒處理 → 404
  if (req.method === "OPTIONS") {
    // 使用 204(No Content)是因為 Preflight 只需要 header,不需要 response body。
    // 因為早期瀏覽器 對於 HTTP Status Code 支援度不佳
    // 如過是部分的系統可能會回 200 以求最大相容性
    return res.sendStatus(204);
  }

  next();
});

// 後端 API
app.get("/", (req, res) => {
  res.send("Server is running!");
});

app.listen(port, () => {
  console.log(`Server running on ${port}`);
});

⚠ 如果 HTTP Request 不是由瀏覽器發起, (例如 Server-to-Server、curl、Postman),就根本不會有 CORS 這一層限制。如果後端 API 需要防禦這些非瀏覽器發起的,或是防禦非預期 HTTP Request ,可以用以下防禦策略:

瀏覽器威脅(跨站)

  • CSRF Token
  • SameSite Cookie

非瀏覽器 / 機器人 / 服務

  • Authorization Header(JWT)
  • 自訂 Header + 驗證
  • Rate limit / Firewall(API 防禦機制)

CORS 不是伺服器安全機制

CORS 是瀏覽器用於保護使用者的一種安全機制,不是伺服器的 API 安全機制例如:爬蟲、 curl 、 postman 或是網路攻擊工具依然可以發出大量的 HTTP Request 到後端伺服器的 API 上面去。伺服器端要自己實作 API 安全的身分驗證、授權與流量控管,必要時可以搭配防火牆做安全防禦。

CORS 的機制

CORS 是瀏覽器在「收到 response 之後」決定要不要交給 JavaScript 使用的規則,而不是伺服器用來拒絕請求的防火牆。

CORS 分為 Simple Request Preflight (OPTIONS) Reques 兩種流程,只是 CORS 的請求流程分類,本身並不決定是否攜帶 Cookies 。是否會攜帶 Cookies,取決於瀏覽器端的 credentials 設定,以及後端回傳的 CORS response header 與 cookie 的 SameSite 屬性。

至於 CORS 的 cookies 前後端操作方法會在後面統一解釋,因為這部分是個大坑。

Simple Request

Simple Request 是「為了不破壞舊網站而保留的特例」,不是效能最佳化設計,少一次 RTT 單純是額外的附加效果

雖然 Simple Request 可以少一次 Preflight(OPTIONS) ,少一次 RTT(Round-Trip Time) ,讓網頁反應時間變快,但其出現的關鍵原因是為了相容在 CORS 出現以前的 Web 生態功能,反應時間變快,只是其出現的附加作用。

CORS 出現以前(2000 年前後)的 Web 世界, 那個時代即使有 JavaScript,但是尚未有 XMLHttpRequest 與現代意義的 AJAX,JavaScript 幾乎無法主動發送與處理 HTTP Request / Response。,沒有動態網頁,所有的網頁全是以 HTML 功能向後端伺服器送出 Request 後,後端伺服器在處理完畢後回傳整頁的 HTML 網頁,或是回傳指定網址跳轉資訊。

那時候的 HTTP 互動完全依賴 HTML 的以下標籤互動:

<img src="http://example.com/image.jpg" />
<form action="https://example.com/transfer" method="POST"></form>
<link rel="stylesheet" href="http://example.com/style.css" />
<script src="http://example.com/lib.js"></script>
<iframe src="...">

預設全是可以跨源請求,只要 domain 相同就會自動攜帶 cookies,尚未有 SameSite 與 CORS 的限制概念。

Simple Request 的設計多是為了相容舊時代 Web 的行為而設計的。


⚠ Simple Request 並不是由「HTML Element 或 JavaScript fetch」來區分,而是由瀏覽器判斷 Request 是否符合 Simple Request 的條件來判斷。

雖然 Simple Request 的設計目的是為了相容舊時代由 HTML Element(如 form、img)所產生的請求行為,但現代瀏覽器中,由 JavaScript fetch 發起的 Request,只要符合 Simple Request 的規範條件,同樣會被視為 Simple Request,而不會觸發 Preflight (OPTIONS)。

以下為一個符合 Simple Request 的 fetch 範例,模擬發送 form element http request:

fetch("https://api.example.com/data", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: "a=1&b=2",
});

Simple Request 的瀏覽器檢查規則:

Method 只能為: GET 、 POST 、 HEAD

Request Header 只能使用 Simple Header :

Accept
Accept-Language
Content-Language
Content-Type(但有限制,見下)

Content-Type(如果有)只能是以下三種:

application/x-www-form-urlencoded
multipart/form-data
text/plain

只要以上三個條件都符合,瀏覽器的 CORS 就會走 Simple Request 。

Simple Request 流程:

CORS Request 符合 Simple Request
|
|  瀏覽器送出真正的 Request
|

Server
|
|  返回 Response ,並在 header 包含 CORS 規則
|

瀏覽器檢查 Response header ,決定是否要處理該 Response ;決定 JavaScript 能否讀取 Response 內容

Preflight (OPTIONS) Request

reflight 的本質就是「在發送 HTTP Request 前,瀏覽器先幫你問一次:這樣做行不行?」

當瀏覽器要送出 CORS Request 時候,檢查不符合 Simple Request 規則時候,就會走 Preflight (OPTIONS) Request 流程。這時會瀏覽器會先向後端伺服器先送出 Preflight (OPTIONS) Request ,之後檢查返回的 Request http cors header ,檢查規則,是否與即將送出的真正的 Request CORS 相符符合伺服器規則的話就送出真正的 Request ,不符合的話,就不發送真正的 Request ,並顯示 CORS Error 訊息。

Preflight 的 http method 是 OPTIONS ,作用是詢問後端伺服器是否支援否某些操作,在決定下一步驟要如何。

其 OPTIONS 內容會類似如下內容

OPTIONS /api/login
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

整個流程會是如以下:

CORS Request 不符合 Simple Request
  │
  │  OPTIONS  第一個 RTT
  │
  ▼
Server
  │
  │  OPTIONS response 會包含 Server 支援的 CORS 操作項目
  │
  ▼
Browser -----------------> 瀏覽器比對不符合 Server 的 CORS 操作,停止發送真正的 Request ,並顯示 CORS Error 訊息。
  │
  │  真正 request 第 2 個 RTT
  │
  ▼
Server
  │
  │  response
  │
  ▼
Browser

CORS 的 Cookies 操作(大坑)

Cookies 的設定較為複雜,其中還牽扯後端伺服器產生 Cookies 是否允許跨站,還有 CORS 設定是否允許 Credentials ,前端預設 CORS 不會攜帶 Credentials ,以及前端的 Credentials 是否為 include 等等設定。這邊會從後端產生 Cookies 設定開始說起。

後端產生 Cookies 時候就要設定可以跨網域攜帶

我先以 node.js express 示範一段後端是怎麼後端伺服器是怎麼設定 Cookies 規則的。

import express from "express";
import cookieParser from "cookie-parser";

const app = express();
const port = 2000;

// 解析 Cookie(req.cookies)
app.use(cookieParser());

app.get("/set-cookie", (req, res) => {
  res.cookie("session_id", "abc123", {
    httpOnly: true, // 瀏覽器端的 JavaScript (如 document.cookie) 無法讀取
    secure: true, // 只允許在 HTTPS 連線時傳送 cookie , false 則是 http 跟 https 都會傳送 cookie
    sameSite: "lax", // 限制跨站請求攜帶 cookie(允許使用者主動導覽的 GET), sameSite 設定後面會有一小節專門說明跨站設定
    maxAge: 1000 * 60 * 60, // cookie 從現在起 1 小時後過期(毫秒)
    path: "/", // 這個 cookie 在那些 URL 路徑會發送,當為 / 時候代表整個網站所有路徑都會攜帶此 cookie
  });
  res.json({ message: "Cookie set" });
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

Cookie 的跨站設定重點在 sameSite 這個參數的值,可用設定分別詳述如下:

  • lax: 限制跨站請求攜帶 cookie ,但是允許使用者主動導覽的 GET 跨站攜帶。
  • strict: 嚴格禁止跨網域攜帶 cookie 。
  • none: 允許跨網域攜帶。

補充: cookies 的 SameSite 是後來補的洞,因為早期 Simple Request 不能擋,且會攜帶 cookies ,所以就在 cookies 層阻擋。在非常早期的 Simple Request 幾乎不管是不是跨域,都會攜帶 cookies ,但是在現代瀏覽器則是會根據 SameSite 決定跨域可不可以攜帶 cookies 。

重要補充: 在現代瀏覽器(Chrome 80+)規定,如果設定 SameSite: "none",除非網域是 localhost ,否則必須同時加上 Secure: true(即必須透過 HTTPS),否則瀏覽器會拒絕存取該 Cookie。

額外補充: 在網址為 localhost 的本機測試環境,瀏覽器會允許使用 http 攜帶 Cookies ,但是在其他非 localhost 網域自從 2020 年 Chrome 80+ 版本開始以後的瀏覽器,就強制要使用 https ,也就是 secure: true 才允許攜帶 Cookies ,若有非 localhost 的測試需求,建議使用 Reverse Proxy 搭配 SSL 憑證(如 mkcert)來模擬真實的 https 環境。

Cookies 的跨域要先在後端產生 Cookies 時候,就在 Cookies 層設定 sameSite: 'none' 才能在 CORS 時候攜帶

後端的 CORS 攜帶 Cookies 的設定

// 這裡先不討論多網域的白名單處理,先不用套件的方式逐一說明,後端伺服器是如何處理 CORS Cookies

// CORS middleware
app.use((req, res, next) => {
  // Access-Control-Allow-Origin 不能為 * ,必須明確指定晚整的網域
  res.setHeader("Access-Control-Allow-Origin", "https://frontend.example.com");

  // Credentials 必須為 true , CORS 規則才會允許攜帶 cookies
  res.setHeader("Access-Control-Allow-Credentials", "true");
  res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");

  // Preflight(OPTIONS)直接回傳 204
  // OPTIONS 沒處理 → 404
  if (req.method === "OPTIONS") {
    return res.sendStatus(204); // No Content
  }

  next();
});

前端 CORS 預設不會攜帶 cookies

這裡以 JavaScript fetch 來說明關於前端的 CORS Cookies 是如何處理的,重點在 fetch 的 credentials 這個參數,如果沒有這個參數,不管是同源,還是非同源,預設都不會在 Request 帶 Cookies 。

fetch("https://api.example.com/profile", {
  credentials: "include",
});

在 credentials 有三個設定值,分別描述如下:

  • include: 不管事同源還是非同源,都會帶 Cookies
  • same-origin: 只有與網頁同源,才會帶 Cookies ,現代瀏覽器 fetch 預設設定。
  • omit: 用於確保瀏覽器絕對不會帶 Cookies

Simple Request 又帶有 CORS Cookies (存在,但是不常去處理)

Simple Request 又帶有 CORS Cookies 這個條件實際上是存在的,因為早期瀏覽器在 SOP 出現以前,會在 Request 自動戴上 Cookies ,且也沒有檢查網域是否與網頁相同,所以才有這種特殊的作法存在。

大致原則就是瀏覽器會檢查 Cookies 的 SameSite 設定是否符合 Request 目標的同源或是跨源設定,符合就的時候,如該 Request 符合 Simple Request 標準,就會自動帶 Cookies ,這是為了相容舊時代的瀏覽器行為而保留的作法,不過如果後端沒有在 Response 明確對該 Cookies 做規則處理,通常瀏覽器會在收到 Response 後自動將 Cookie 捨去不予處理。

總結來說: 是否攜帶 cookies,與是否為 Simple Request 沒有直接因果關係 ,而是取決於:

  • Cookie 的 SameSite 設定
  • Request 是否符合瀏覽器允許攜帶 cookies 的條件
  • (CORS 情境下) 前端 credentials 與後端 Allow-Credentials

後端以 cors 套件設定,以及前端 CORS fetch 有 cookies 綜合使用範例

後端程式碼

import express from "express";

// node.js CORS 處理套件
import cors from "cors";

// 要有該套件, node.js 才有辦法讀取 request 的 cookies
import cookieParser from "cookie-parser";

const app = express();
const port = 2000;

/**
* 你唯一允許跨域存取的前端網域
* ⚠️ 一定要是完整 origin(含 protocol + domain + port),沒有設定 port 就會用 protocol 預設的 port
*/
// 此為 VS code 的 Liveserver 預設網址
const FRONTEND_ORIGIN = "http://127.0.0.1:5500";

/**
* CORS 設定物件
*/
app.use(
cors({
/**
* 告訴瀏覽器:
* - 只允許這個特定 Origin 跨域存取
* - credentials: true 時,這裡「不能用 '*'」
*/
origin: FRONTEND_ORIGIN
/**
* 允許跨域攜帶 cookies / Authorization
* - 會讓後端回:
*   Access-Control-Allow-Credentials: true
*/,

credentials: true
/**
* 允許的 HTTP methods(主要給 Preflight 用)
*/,

methods: ["GET", "POST", "PUT", "DELETE"]
/**
* 允許前端實際送出的 request headers
* - 非 simple request 要自訂允許的 header 欄位,要補在這裡
*/,

allowedHeaders: ["Content-Type", "Authorization"]
/**
* Preflight 快取時間(秒)
* - 瀏覽器在這段時間內不會一直重送 OPTIONS
*/,

maxAge: 86400
/**
* OPTIONS 成功時回傳的狀態碼
* - 204 = No Content(語意最正確)
* 因為早期瀏覽器 對於 HTTP Status Code 支援度不佳
* 如過是部分的系統可能會回 200 以求最大相容性
*/,

optionsSuccessStatus: 204,
})
);

/**
* 讓 Express 自動處理所有路徑的 OPTIONS(Preflight)
* - cors 套件會幫你回正確的 CORS headers
*/
app.options("*", cors());

/**
* 解析 cookies(只是為了讓你能讀 req.cookies)
* - 跟「能不能跨域帶 cookies」是兩件不同的事
*/
app.use(cookieParser());

/* ---------------- API 區 ---------------- */

/**
* 示範:後端設置 cookie
*
* ⚠️ 跨域 cookie 必要條件:
* 1) 後端:credentials: true
* 2) 前端:fetch credentials: 'include'
* 3) cookie:
*    - sameSite: 'none'
*    - secure: true(正式環境必須 HTTPS)
*/
app.get("/set-cookie", (req, res) => {
res.cookie("session_id", "abc123", {
httpOnly: true, // 前端 JS 讀不到(安全)
secure: false, // ⚠️ 本機 http 測試可以先用 false ,不過正式環境必須為 true
sameSite: "none", // 跨站/跨域 cookie 必備
maxAge: 1000 * 60 * 60, // 一小時,毫秒
path: "/",
});

res.json({ ok: true, message: "cookie set" });
});

/**
* 示範:需要 cookie 的 API
*/
app.get("/profile", (req, res) => {
const sessionId = req.cookies?.session_id;
res.json({ sessionId });
});

/**
* 健康檢查
*/
app.get("/", (req, res) => {
res.send("Server is running!");
});

app.listen(port, () => {
console.log(`Server running on ${port}`);
});

前端 fetch 帶 cookies 的程式碼

async function getProfile() {
try {
const response = await fetch("http://localhost:2000/profile", {
credentials: "include", // include 為要求跨域也要帶 cookies ,沒有該設定預設為 same-site
});
const data = await response.json();
console.log("Profile Data:", data);
} catch (error) {
console.error("CORS Error or Network Error:", error);
}
}

getProfile();

Debug Checklist(可執行檢查順序)

第一步:排除基礎連線問題

脫離瀏覽器測試: 先使用 Postman 或 curl 等非瀏覽器環境,直接呼叫 API。

  • 如果 Postman 也不通:那是 API 本身邏輯或網路問題。
  • 如果 Postman 會通:確定是瀏覽器的 CORS 限制,繼續往下。
  • 確認 API 安全機制: 檢查後端是否需要 API Key 或 Authorization Header,確保不是因為沒給憑證而被伺服器拒絕。

第二步:判斷請求類型

檢查是否為 簡單請求 (Simple Request):

  • 觀察 DevTools Network 分頁,如果沒有出現 `OPTIONS` 請求,就是簡單請求。
  • 發生錯誤時: 請看 Console 訊息,檢查後端 `Access-Control-Allow-Origin` 是否包含前端網域。


檢查 預檢請求 (Preflight / OPTIONS):

  • 如果有 OPTIONS 請求但沒送出真正的 Request:檢查後端的 Access-Control-Allow-MethodsHeaders 是否允許該次操作。
  • 如果 OPTIONS 回傳 404: 代表後端沒有正確處理 OPTIONS 方法(例如 Express 沒掛載 cors 中間件或沒寫 app.options() )。

第三步:Cookies 專題排查 (最常踩的坑)

後端 Cookie 設定:

  • SameSite 是否設為 None ?
  • 若設為 None,Secure 是否有設為 true ?(非 localhost 網域,跟正式環境必需條件)。

前端 Request 設定

  • fetchaxios 是否有加上 credentials: "include" ​ 。

後端接收檢查:

  • 是否已安裝並使用 cookie-parser 等套件解析 Cookie?
  • 嘗試印出 req.cookies 確認伺服器層級是否有收到內容。

💡 小訣竅

遇到 CORS 錯誤時,一般在非瀏覽器環境先排除後端 API 非 CORS 問題後,通常 看瀏覽器 Console 的報錯訊息 多可以大概知道原因,它通常會直接告訴你是哪個 Header 不符合規則(例如:The 'Access-Control-Allow-Origin' header contains multiple values... )。之後在根據 console 訊息逐一檢查前後端的 CORS 設定,通常可以找到問題原因。

參考

簡單弄懂同源政策 (Same Origin Policy) 與跨網域 (CORS)

Using Fetch


留言
avatar-img
weijie 的各種記事
0會員
7內容數
原本是打算用來當作技術部落格的,不過以後也會把各種雜記紀錄於此
weijie 的各種記事的其他內容
2026/01/13
探討同源政策 (Same-Origin Policy, SOP) 如何在網頁互動性與安全性之間取得平衡。闡述 JavaScript 的誕生、初期面臨的安全問題,以及 SOP 如何應運而生並逐步演進。
Thumbnail
2026/01/13
探討同源政策 (Same-Origin Policy, SOP) 如何在網頁互動性與安全性之間取得平衡。闡述 JavaScript 的誕生、初期面臨的安全問題,以及 SOP 如何應運而生並逐步演進。
Thumbnail
2025/12/17
如何在 Node.js 專案中,從 console.log 逐步演進到生產環境所需的日誌解決方案 Winston。本文深入探討 Winston 的核心概念,包括日誌等級、輸出管道 (Transport)、結構化日誌 (Structured Logging),以及格式化 (Format) 的應用
Thumbnail
2025/12/17
如何在 Node.js 專案中,從 console.log 逐步演進到生產環境所需的日誌解決方案 Winston。本文深入探討 Winston 的核心概念,包括日誌等級、輸出管道 (Transport)、結構化日誌 (Structured Logging),以及格式化 (Format) 的應用
Thumbnail
2025/12/13
本文將深入探討 Node.js 中常用的 Morgan HTTP request middleware。我們將從 Morgan 的核心功能、未使用 Morgan 的潛在問題,以及使用 Morgan 後的優勢等方面進行說明。
Thumbnail
2025/12/13
本文將深入探討 Node.js 中常用的 Morgan HTTP request middleware。我們將從 Morgan 的核心功能、未使用 Morgan 的潛在問題,以及使用 Morgan 後的優勢等方面進行說明。
Thumbnail
看更多
你可能也想看
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
從瀏覽器console看到類似這個error:  ..... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource 表示遇到CORS的
Thumbnail
從瀏覽器console看到類似這個error:  ..... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource 表示遇到CORS的
Thumbnail
這篇文章涵蓋了HTTP 方法、JWT 認證授權機制、CORS 設定、HTTP 狀態碼,以及LeetCode熱門題目(Longest Substring Without Repeating Characters、Valid Parentheses)的解法,適合學習Web開發以及後端技術的讀者。
Thumbnail
這篇文章涵蓋了HTTP 方法、JWT 認證授權機制、CORS 設定、HTTP 狀態碼,以及LeetCode熱門題目(Longest Substring Without Repeating Characters、Valid Parentheses)的解法,適合學習Web開發以及後端技術的讀者。
Thumbnail
VUE 在localhost執行debug 如何自定Debug SeverIP或Port,解決CORS問題
Thumbnail
VUE 在localhost執行debug 如何自定Debug SeverIP或Port,解決CORS問題
Thumbnail
互聯網的時代中我們幾乎都離不開網路,那如果能夠對於Web具備基礎的知識,就能夠讓我們在使用網路的過程中提升風險意識,以減少被竊取、盜用的風險,進而保護個人資產,因此多一份知識在身上也就等於多了一份防身的武器,一天學一點,透過微小習慣的積累讓我們享受複利的效應。OO 如何運作? 📷
Thumbnail
互聯網的時代中我們幾乎都離不開網路,那如果能夠對於Web具備基礎的知識,就能夠讓我們在使用網路的過程中提升風險意識,以減少被竊取、盜用的風險,進而保護個人資產,因此多一份知識在身上也就等於多了一份防身的武器,一天學一點,透過微小習慣的積累讓我們享受複利的效應。OO 如何運作? 📷
Thumbnail
Cross-Origin Resource Sharing 簡稱 CORS,中文為跨來源資源共享。 上一篇提到web瀏覽器有同源政策的限制,而CORS則是一種安全確認機制,讓瀏覽器和伺服器之間能確保安全的進行cross origin資源共享,即若伺服器同意,即可達成跨來源資源共享。
Thumbnail
Cross-Origin Resource Sharing 簡稱 CORS,中文為跨來源資源共享。 上一篇提到web瀏覽器有同源政策的限制,而CORS則是一種安全確認機制,讓瀏覽器和伺服器之間能確保安全的進行cross origin資源共享,即若伺服器同意,即可達成跨來源資源共享。
Thumbnail
在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
Thumbnail
在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
在開發前後端分離架構時,使用兩個不同網域所遇到跨域請求問題。特別是在POST請求時行為差異大,揭示了「簡單請求」與「預檢請求」的關鍵差異。簡單請求不需預檢,但application/json會觸發預檢請求,需透過特定設定解決。分享這篇文章希望幫助開發者有效處理跨域問題。
Thumbnail
在開發前後端分離架構時,使用兩個不同網域所遇到跨域請求問題。特別是在POST請求時行為差異大,揭示了「簡單請求」與「預檢請求」的關鍵差異。簡單請求不需預檢,但application/json會觸發預檢請求,需透過特定設定解決。分享這篇文章希望幫助開發者有效處理跨域問題。
Thumbnail
AWS CloudFront + S3 遇到 CORS 解決方式
Thumbnail
AWS CloudFront + S3 遇到 CORS 解決方式
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News