如何在Mountebank中统一配置通用CORS响应头?
Access to fetch at 'http://localhost:8080/xxx/api/secured/policies' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
用Mountebank做mock服务器开发React应用时碰到了上面的CORS错误。已经找到OPTIONS预检请求的相关处理,但仅处理预检还不够——必须给所有响应存根添加以下CORS头配置才能解决问题:
{ "is": { "headers": { "Content-Type": "application/json", "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Origin": "*" } } }
单个存根加了之后能正常运行,但项目里存根数量多,不想逐个修改(目前靠CORS-unblock插件临时解决)。想知道有没有办法统一添加这些CORS头?
1. 使用全局响应装饰器(最推荐)
Mountebank支持通过decorate函数全局修改所有响应,不用逐个调整存根。在启动Mountebank的配置脚本里添加以下逻辑:
const mb = require('mountebank'); // 定义要添加的CORS头 const corsHeaders = { 'Content-Type': 'application/json', 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Methods': '*', 'Access-Control-Allow-Origin': '*' }; // 启动服务器时挂载全局装饰器 const server = mb.create({ port: 8080, decorate: (request, response) => { // 合并原有响应头与CORS头,避免覆盖自定义头 response.headers = { ...response.headers, ...corsHeaders }; return response; } }); server.start().then(() => console.log('Mountebank已启动,全局CORS头已生效'));
这个方法会自动给所有存根的响应(包括OPTIONS预检请求)加上CORS头,一次性解决所有跨域问题。
2. 批量更新存根配置
如果不想用装饰器,可以写个简单脚本批量修改所有存根文件:
const fs = require('fs'); const path = require('path'); const corsHeadersConfig = { "is": { "headers": { "Content-Type": "application/json", "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Origin": "*" } } }; // 替换为你的存根文件目录 const stubsDir = './stubs'; fs.readdirSync(stubsDir).forEach(file => { if (file.endsWith('.json')) { const filePath = path.join(stubsDir, file); const stub = JSON.parse(fs.readFileSync(filePath, 'utf8')); // 合并原有header配置,保留自定义内容 if (stub.is) { stub.is.headers = { ...stub.is.headers, ...corsHeadersConfig.is.headers }; } else { stub.is = corsHeadersConfig.is; } fs.writeFileSync(filePath, JSON.stringify(stub, null, 2)); console.log(`已更新${file}的CORS配置`); } });
运行脚本后,所有存根会自动带上CORS头配置,后续启动Mountebank无需额外处理。
3. 全局OPTIONS预检存根(补充方案)
如果需要单独处理OPTIONS请求,可以添加一个全局存根专门响应预检,再配合全局装饰器覆盖其他请求的CORS头:
{ "port": 8080, "stubs": [ { "predicates": [ { "equals": { "method": "OPTIONS" } } ], "responses": [ { "is": { "statusCode": 200, "headers": { "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Origin": "*" } } } ] } // 其他业务存根... ] }
不过这种方法需要额外处理非OPTIONS请求的CORS头,效率不如全局装饰器。
内容的提问来源于stack exchange,提问作者Carlos Jaime C. De Leon

