:基于 @koa/cors 中間件的 CORS 實現(xiàn)指南)
后端微服務云原生【免費下載鏈接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 項目地址https://gitcode.com/gh_mirrors/mi/midway點擊查看免費下載導讀在前后端分離的現(xiàn)代 Web 開發(fā)中瀏覽器同源策略導致的跨域CORS問題幾乎是每個全棧開發(fā)者都要面對的第一道坎。本文聚焦 Midway Hooks 項目Node.js 全棧/前后端一體化框架的 Hooks 體系中如何通過koa/cors中間件配置跨域覆蓋從依賴安裝、全局中間件掛載到全部核心配置項逐一拆解的完整流程。讀完本文你將能夠在 Midway Hooks 項目中獨立完成跨域配置并理解origin、credentials、allowMethods等關鍵參數(shù)對瀏覽器預檢請求與響應頭的影響。背景為什么 Midway Hooks 需要 CORS 配置Midway Hooks 是基于函數(shù)式編程風格Functional API構建 API 的開發(fā)模式開發(fā)者不再編寫傳統(tǒng) Controller而是通過Api()、Get()等函數(shù)式裝飾器定義接口配合useContext()訪問請求上下文。由于這種模式天然面向前后端一體化場景前端頁面與后端接口經(jīng)常運行在不同的端口甚至不同域名上瀏覽器便會基于同源策略攔截跨源請求。從倉庫中的示例項目 samples/functional-api-service 可以看出Hooks 應用的入口是 src/configuration.ts其中通過imports注冊midwayjs/koa等框架組件。這正是 CORS 中間件需要掛載的位置——在 Hooks 體系中中間件統(tǒng)一通過hooks()配置對象的middleware數(shù)組注入koa/cors作為標準 Koa 中間件可以無縫接入。使用方法第一步安裝依賴在項目根目錄執(zhí)行以下命令安裝koa/corsnpm install koa/corskoa/cors是 Koa 生態(tài)中最常用的 CORS 中間件基于koa的洋蔥模型實現(xiàn)專門用于向響應報文寫入Access-Control-*系列跨域響應頭。第二步在 configuration.ts 中啟用Hooks 應用通過createConfiguration定義應用配置imports中注冊 Koa 框架與hooks()配置。將cors()中間件放入hooks()的middleware數(shù)組即可對全部接口啟用跨域import { createConfiguration, hooks, } from midwayjs/hooks; import * as Koa from midwayjs/koa; import cors from koa/cors; export default createConfiguration({ imports: [ Koa, hooks({ // 全局啟用 CORS允許任意來源訪問 middleware: [ cors({ origin: * }), ], }), ], });cors()返回的是一個標準 Koa 中間件函數(shù)因此它同樣可以出現(xiàn)在 Midway Hooks 支持的任意中間件層級中。倉庫文檔 site/docs/hooks/middleware.md 展示了中間件的三種掛載位置CORS 均可按需選擇全局中間件放在configuration.ts的hooks({ middleware: [...] })中對所有接口生效即上述示例文件級中間件在 API 文件中導出config: ApiConfig { middleware: [logger, cors] }對該文件內(nèi)所有 API 函數(shù)生效單函數(shù)中間件通過Middleware(logger, cors)包裹單個Api(Get(), ...)函數(shù)僅對該函數(shù)生效。其中「文件級」與「單函數(shù)級」兩種方式無需帶參數(shù)調(diào)用cors直接傳入函數(shù)本身即可例如middleware: [logger, cors]而全局方式通常顯式調(diào)用cors({ origin: * })以明確配置項。核心配置項詳解koa/cors支持的配置項如下這也是 Midway Hooks 中 CORS 能力的完整參數(shù)面/** * CORS middleware * * param {Object} [options] * - {String|Function(ctx)} origin Access-Control-Allow-Origin, default is request Origin header * - {String|Array} allowMethods Access-Control-Allow-Methods, default is GET,HEAD,PUT,POST,DELETE,PATCH * - {String|Array} exposeHeaders Access-Control-Expose-Headers * - {String|Array} allowHeaders Access-Control-Allow-Headers * - {String|Number} maxAge Access-Control-Max-Age in seconds * - {Boolean|Function(ctx)} credentials Access-Control-Allow-Credentials, default is false. * - {Boolean} keepHeadersOnError Add set headers to err.header if an error is thrown * return {Function} cors middleware * api public */逐項說明如下配置項對應響應頭默認值說明originAccess-Control-Allow-Origin請求頭中的Origin允許的跨域來源可傳字符串如*或http://127.0.0.1:7001也可傳函數(shù)(ctx) string動態(tài)返回。啟用credentials時不能使用*allowMethodsAccess-Control-Allow-MethodsGET,HEAD,PUT,POST,DELETE,PATCH允許的 HTTP 方法可傳字符串或字符串數(shù)組exposeHeadersAccess-Control-Expose-Headers無允許前端 JS 讀取的響應頭列表默認情況下瀏覽器只能讀取少量安全響應頭allowHeadersAccess-Control-Allow-Headers請求頭中的Access-Control-Request-Headers允許的請求頭列表可傳字符串或字符串數(shù)組maxAgeAccess-Control-Max-Age無預檢請求Preflight結果可緩存的秒數(shù)減少瀏覽器重復發(fā)送 OPTIONS 請求credentialsAccess-Control-Allow-Credentialsfalse是否允許攜帶 Cookie 等憑證可傳布爾值或函數(shù)(ctx) booleankeepHeadersOnError無false中間件執(zhí)行報錯時是否將已設置的跨域響應頭寫入err.headers便于上層錯誤處理時透傳origin控制允許的來源origin是 CORS 配置中最核心的選項。默認行為是回顯請求頭中的Origin值即允許任意來源。生產(chǎn)環(huán)境若要收緊應顯式指定為具體域名例如cors({ origin: http://127.0.0.1:7001 })需要根據(jù)請求動態(tài)判斷來源時可以傳入函數(shù)cors({ origin: (ctx) { // 依據(jù) ctx.request.header.origin 或業(yè)務邏輯返回允許的來源 return https://example.com; }, })注意根據(jù) CORS 規(guī)范Access-Control-Allow-Origin一旦設置為*瀏覽器要求Access-Control-Allow-Credentials必須為false反之只要啟用credentials: trueorigin就不能是通配符*必須給出明確的來源或函數(shù)動態(tài)返回值否則瀏覽器會拒絕響應。credentials允許攜帶 Cookie 與憑證跨域請求若需要攜帶 Cookie例如fetch(url, { credentials: include })或 XMLHttpRequest 的withCredentials true服務端必須開啟credentials: truecors({ origin: http://127.0.0.1:7001, credentials: true, })如前所述該配置與origin: *互斥。倉庫文檔 site/docs/extensions/cross_domain.md 中關于通用跨域組件的配置示例同樣強調(diào)了這一點可互為印證。allowMethods 與 allowHeaders預檢請求的通行證當瀏覽器發(fā)起帶自定義頭如Content-Type: application/json、Authorization的跨域請求時會先發(fā)送 OPTIONS 預檢請求Preflight。服務端通過Access-Control-Allow-Methods與Access-Control-Allow-Headers告知瀏覽器允許的方法與請求頭匹配時瀏覽器才會放行真實請求。allowMethods默認覆蓋GET,HEAD,PUT,POST,DELETE,PATCH基本滿足 RESTful API 場景若接口使用了自定義方法如OPTIONS之外的擴展可按需追加cors({ allowMethods: [GET, POST, PUT, DELETE, PATCH, OPTIONS], allowHeaders: [Content-Type, Authorization, X-Requested-With], })maxAge緩存預檢結果maxAge單位為秒用于指示瀏覽器緩存本次預檢響應避免每個跨域請求都觸發(fā)一次額外的 OPTIONS 往返。高頻調(diào)用的接口建議設置較大值例如cors({ maxAge: 86400 })緩存一天。exposeHeaders 與 keepHeadersOnErrorexposeHeaders默認情況下瀏覽器只向 JS 暴露Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma等安全響應頭自定義響應頭如分頁信息X-Total-Count需要通過該選項顯式聲明后才能被前端讀取keepHeadersOnError當后續(xù)中間件或業(yè)務代碼拋出異常時是否保留已寫入的跨域頭。若你的應用有統(tǒng)一的全局錯誤處理中間件且希望錯誤響應仍攜帶 CORS 頭應將其設為true否則錯誤響應可能因缺少 CORS 頭而被瀏覽器攔截前端只能看到晦澀的網(wǎng)絡錯誤而非真實錯誤信息。與通用跨域組件的差異倉庫還提供了面向傳統(tǒng)框架midwayjs/faas、midwayjs/web、midwayjs/koa、midwayjs/express的通用跨域組件midwayjs/cross-domain它通過Configuration({ imports: [crossDomain] })引入并支持在 config.default.ts 中以配置項形式聲明cors與jsonp模式詳見 site/docs/extensions/cross_domain.md。而本文所述的 Hooks 方式與它的本質(zhì)區(qū)別在于Midway Hooks 的函數(shù)式配置體系中CORS 被當作一個普通 Koa 中間件注入hooks({ middleware: [...] })配置即代碼無需額外的組件裝載與配置中心適合以函數(shù)式 API 為主的新項目若你的項目同時存在傳統(tǒng) Controller 與 Hooks 兩種編碼風格也可以按需混用這兩種跨域方案。常見問題排查當發(fā)現(xiàn) CORS 配置不生效時可以對照倉庫文檔 site/docs/extensions/cross_domain.md 中總結的排查順序逐項確認確認請求確實跨域同源策略只約束瀏覽器環(huán)境服務端調(diào)用Node.js 內(nèi)部請求、curl 等不受 CORS 限制不設置任何配置也能成功確認請求發(fā)自瀏覽器只有瀏覽器XMLHttpRequest、Fetch API才會執(zhí)行同源策略檢查確認請求帶有Origin頭同源請求或部分瀏覽器場景如地址欄直達不帶Origin頭CORS 中間件據(jù)此無法觸發(fā)響應頭寫入檢查預檢請求OPTIONS是否被中間件正確處理確認allowMethods/allowHeaders與實際請求匹配檢查credentials與origin的搭配credentials: true時origin不能為*否則瀏覽器會因響應頭非法而攔截。典型的 CORS 報錯形如Access to fetch at http://127.0.0.1:7002/ from origin http://127.0.0.1:7001 has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource.該報錯意味著服務端響應中缺少Access-Control-Allow-Origin頭優(yōu)先檢查中間件是否已掛載、請求是否真的帶了Origin頭、以及錯誤響應是否因keepHeadersOnError為false而丟失了跨域頭。小結在 Midway Hooks 中配置 CORS 只需三步安裝koa/cors、在configuration.ts的hooks({ middleware })中掛載cors()、按需設置origin、credentials、allowMethods等參數(shù)。這套方案完全復用 Koa 生態(tài)的中間件能力代碼量小、作用域可控全局/文件級/單函數(shù)級均可并天然適配 Hooks 函數(shù)式 API 的開發(fā)范式。合理設置maxAge與keepHeadersOnError還能顯著優(yōu)化跨域請求的性能與錯誤排查體驗。如需進一步了解中間件的三種掛載層級與更多中間件用法可繼續(xù)閱讀倉庫文檔 site/docs/hooks/middleware.md通用框架下的跨域組件含 JSONP則見 site/docs/extensions/cross_domain.md。贊分享后端微服務云原生【免費下載鏈接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 項目地址https://gitcode.com/gh_mirrors/mi/midway點擊查看免費下載相關推薦Midway 跨域組件cross-domain完全指南CORS 與 JSONP 配置實戰(zhàn)Midway 跨域組件cross domain完全指南CORS 與 JSONP 配置實戰(zhàn) 導讀 Midway 提供了開箱即用的通用跨域組件 midway后端微服務云原生Wasp 多域名 CORS 配置實戰(zhàn)基于全局中間件管理跨域訪問Wasp 多域名 CORS 配置實戰(zhàn)基于全局中間件管理跨域訪問 本篇指南講解如何在 Wasp 應用中通過自定義全局中間件global middlewareWeb框架后端前端CLI開發(fā)工具OpenCloud 中的 CORS 中間件rs/cors 配置、實現(xiàn)原理與實戰(zhàn)指南OpenCloud 中的 CORS 中間件rs/cors 配置、實現(xiàn)原理與實戰(zhàn)指南 導讀 OpenCloud 作為一款提供文件管理、共享與協(xié)同能力的開源平臺后端微服務存儲認證鑒權上一篇告別冗長命令行Chronicle-Core系統(tǒng)屬性文件加載機制詳解與最佳實踐下一篇LeetCode-Go 如何運行 gotest.sh 生成 Codecov 可識別的單一覆蓋率文件 coverage.txt創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考