先判斷瀏覽器是否需要跨來源存取
合作夥伴說其儀表板呼叫你的客戶 API 時,瀏覽器出現 CORS 錯誤。先畫出真正的請求:哪個網頁來源執行 JavaScript、哪個 API 來源接收請求、會傳回甚麼資料,以及是否附帶 cookie 或其他憑證。來源由通訊協定、主機和連接埠組成;不同子網域或連接埠就是不同來源。CORS 決定一個來源的網頁程式能否讀取另一來源的回應,卻不會辨認合作夥伴、授予帳戶權限,亦不會證明該帳戶有權讀取某筆紀錄。這些判斷仍須由 API 處理。
先問這項呼叫是否一定要在瀏覽器執行。若合作夥伴已有受其管理的伺服器,可由雙方伺服器交換憑證,便不涉及瀏覽器的 CORS。若其員工必須直接從儀表板操作 API,瀏覽器存取可能合理,但須明確設計憑證暴露風險、請求範圍及使用者權限。記錄正式儀表板的完整來源,以及受控的測試來源。不要只因萬用字元令示範成功便採用它;先釐清預期讀者,雙方才可理解回應政策。
設定標頭前,先把公開目錄資料和私人客戶或訂單資料分開。真正公開、匿名的端點,有時可以容許任何來源讀取回應,但仍要另行評估服務容量和濫用控制。與已登入使用者相關的回應則是另一項決策。即使容許某個已知來源,也不代表該來源每個請求可信;網頁程式可能被更改,帳戶亦可能失守。伺服器端的身分驗證、逐筆紀錄授權、輸入檢查和運作限制仍須保留。交給開發者的應是逐個端點列明的存取矩陣,而非整個網域共用的開關。
讓回應標頭配合實際請求
如只批准一個儀表板,就在相關 API 回應的 Access-Control-Allow-Origin 寫出其完整來源。若伺服器按收到的 Origin 從許可清單選值,同時送出 Vary: Origin,讓中介快取知道回應會因請求來源而異。遇到未知來源應拒絕,不能原封不動反映傳入字串。直接由伺服器呼叫而沒有 Origin,與已批准的瀏覽器來源意義不同,不應把它當成秘密繞路。成功和錯誤回應都要檢查,合作夥伴才可處理合法的 404 或資料錯誤,而不只看見含糊的瀏覽器失敗。
若瀏覽器必須附帶憑證,回應要指定獲准的來源,並設 Access-Control-Allow-Credentials: true。帶憑證的瀏覽器請求不能配合萬用來源;前端亦須明確選擇是否附帶憑證,跨來源 fetch 預設不會附帶。即使 CORS 標頭正確,亦不能凌駕瀏覽器對第三方 cookie 的限制。若 API 使用 Authorization 標頭傳遞 bearer token,不應直接套用 cookie 的建議;須畫清真正的憑證流程,並讓授權檢查獨立於 CORS。切勿只為省略代理伺服器或伺服器交換,就把秘密 API 金鑰放入可下載的 JavaScript。
某些方法或標頭會令瀏覽器先發出預檢請求:在真正操作前,以 OPTIONS 查問允許的方法和標頭。Access-Control-Request-Method 與 Access-Control-Request-Headers 說明擬進行的呼叫。只回覆該端點實際接受的項目,不要沿用全站的全部放行清單。預檢本身並非更新訂單,而且通常沒有應用程式憑證,因此不要要求 OPTIONS 完成一般業務操作的身分驗證。其後的真正請求仍須驗證身分與權限,並在自己的回應附上適當 CORS 標頭。
端點若提供自訂回應標頭,亦須考慮瀏覽器程式可讀取甚麼。回應內文可能可以讀取,但用於分頁或診斷的標頭,未適當開放時合作夥伴 JavaScript 未必看得到。先判斷該標頭是否屬於公開 API 合約,再只列出真正需要的名稱。不要因整合要求所有標頭,就把內部追蹤編號、cookie 或除錯資料全部開放。請合作夥伴指出程式真正要讀的欄位,並在瀏覽器測試;這樣可分清回應共享問題與應用程式解析問題。
以合作夥伴儀表板作例子
假設中小企向位於 https://dashboard.partner.example 的合作夥伴儀表板提供只讀存貨查詢,而 API 位於 https://api.shop.example。這些名稱只是例子,並非真正已批准的來源。儀表板以 Authorization 標頭要求 JSON;瀏覽器可能先就該標頭預檢,故團隊要同時測試 OPTIONS 和真正的 GET。回應只容許該儀表板來源、所需方法與標頭,並以 Origin 區分快取。API 仍須檢查憑證可否查看指定存貨群組。另一個無關網站即使知道 URL,亦不應獲准讀取回應。
若合作夥伴在另一子網域新增預覽站,這個完整來源是待重新審核的項目,並非正式環境批准的自動延伸。要查明誰管理它、是否使用真實客戶資料,以及何時撤銷存取。籠統匹配所有子網域,可能連遺忘或可由使用者控制的主機一同納入。若預覽只需示例紀錄,應使用隔離的測試 API 或測試身分,而非放寬正式資料的讀取範圍。記錄臨時來源的到期安排,交接整合時移除,並指定許可清單負責人。
命令列請求成功並不足以證明設定正確。非瀏覽器工具不會執行瀏覽器的 CORS 規則;OPTIONS 看似正確,後續 GET 仍可能欠缺標頭。相反,瀏覽器阻止讀取回應時,改變狀態的請求也可能已到達伺服器;CORS 不能取代防止偽造請求的措施。要從真正合作夥伴頁面或同來源的受控頁面測試,查看瀏覽器網絡面板,再對照伺服器紀錄。先分清預檢被拒、身分驗證失敗、重新導向及回應被阻止讀取,才修改設定。
測試邊界並持續維護
建立簡單測試矩陣,包括已批准的正式來源、臨時測試來源、未知來源,以及有憑證和匿名請求。逐項記下預期瀏覽器結果、實際狀態和相關回應標頭。涵蓋獲准回應、無權讀取的紀錄、過期憑證與伺服器錯誤。若 CDN 或代理會快取 API 回應,須在其路徑確認 Vary: Origin;快取若混合不同來源,即使應用程式邏輯正確,交付結果仍可能混亂或不安全。每次更改 API 閘道、身分驗證或夥伴網域時,都要重做這些檢查。
不要把所有瀏覽器失敗都當成 CORS。DNS 錯誤、TLS 失敗、網絡逾時、身分驗證被拒及預檢未處理,是各有不同修復方法的問題。瀏覽器主控台和網絡面板可指出哪次交換失敗;API 紀錄則顯示請求有否到達。若 JavaScript 只報一般網絡錯誤,應檢查真正 HTTP 往來,不要不斷放寬標頭直到錯誤消失。請合作夥伴提供網頁來源、請求方法、標頭、憑證設定、時間及回應狀態,但勿經非正式支援渠道傳送有效憑證或客戶資料。
實務決策是把瀏覽器讀取權限狹窄、清楚地授予指定端點和來源。指定誰可批准新來源、誰負責測試,以及合作終止時誰會撤銷權限。把示例請求和預期標頭放在 API 合約旁。若新功能從公開查詢改為個人化資料,須連同身分驗證、逐筆授權和快取行為一起重看 CORS 規則。這項簡短覆核可避免原本只為方便整合的設定,悄悄變成所有客戶紀錄的安全政策。
把許可清單更改當作存取權變更,預先準備回復方案。部署前記錄現有獲准來源,以及一個已知可用的瀏覽器請求。部署後既要確認新夥伴可用,也要確認無關來源仍不能讀取回應。若閘道與應用程式同時加入標頭,應檢查最終回應有否互相矛盾的值,不要猜測哪一層會勝出。回復時恢復原本較窄的清單,並重做拒絕測試。合作夥伴趕上線而代理或 CDN 設定又同時更改時,這個次序尤其有用。
進行前先確認
- 列出網頁與 API 的完整來源,以及需要由瀏覽器讀取的端點。
- 分別核實預檢、真正回應、身分驗證和逐筆授權。
- 透過真正瀏覽器及中介快取測試獲准與未知來源。


