LoopBack 4 配置通配符后CORS仍不生效问题咨询
我明白你碰到的这个问题有多头疼——明明LoopBack 4默认是启用CORS的,你也在src/index.ts里配置了看起来完全正确的CORS规则,可跨域请求还是被浏览器拦截,提示预检请求没通过,原因是响应里压根没有Access-Control-Allow-Origin这类CORS头。具体场景就是从http://local.example.com向http://localhost:8081/sessions发起XMLHttpRequest时触发了这个错误。
先看一下你提供的配置代码:
// src/index.ts if (require.main === module) { // Run the application const config: ApplicationConfig = { rest: { port: +(process.env.PORT ?? 8081), host: process.env.HOST, // The `gracePeriodForClose` provides a graceful close for http/https // servers with keep-alive clients. The default value is `Infinity` // (don't force-close). If you want to immediately destroy all sockets // upon stop, set its value to `0`. // See https://www.npmjs.com/package/stoppable gracePeriodForClose: 5000, // 5 seconds openApiSpec: { // useful when used with OpenAPI-to-GraphQL to locate your application setServersFromRequest: true, }, cors: { origin: '*', methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', preflightContinue: false, optionsSuccessStatus: 204, credentials: true, }, }, } main(config).catch((err) => { console.error('Cannot start the application.', err) process.exit(1) }) }
你的CORS配置语法是完全符合LoopBack 4要求的,问题大概率出在配置没有被正确应用到应用实例上,下面是几个排查和解决的关键点:
检查
main函数是否正确传递配置:你在index.ts里定义了config并传给了main函数,但要确保main函数内部创建应用实例时,把这个配置参数传递给了应用的构造函数。比如你的main函数应该是这样的:async function main(config: ApplicationConfig) { // 必须把config传入应用构造函数 const app = new MyApplication(config); await app.start(); const url = app.restServer.url; console.log(`Server is running at ${url}`); console.log(`Try ${url}/ping`); return app; }如果
main函数里创建应用时没有传config(比如写成new MyApplication()),那你写的CORS配置就根本不会被加载,自然不会生效。确认应用类没有覆盖CORS配置:检查你的应用类文件(通常是
src/application.ts),看是否在构造函数里重新配置了REST服务器的CORS规则,覆盖了你在index.ts里的设置。如果有类似下面的代码,就会导致你的配置被覆盖,需要删除或统一配置:export class MyApplication extends RestApplication { constructor(options: ApplicationConfig = {}) { super(options); // 这段代码会覆盖index.ts里的cors配置 this.configure(RestBindings.REST_SERVER).to({ cors: { // 其他不同的配置 } }); } }验证预检请求的响应:启动应用后,用
curl发送一个预检OPTIONS请求,手动检查响应头是否包含CORS字段:curl -X OPTIONS http://localhost:8081/sessions -H "Origin: http://local.example.com" -i如果响应头里能看到
Access-Control-Allow-Origin: *(或者你指定的源),说明配置已经生效;如果没有,那就要回到前两步检查配置传递的问题。
按照这几个步骤排查,应该就能解决CORS头不出现的问题了。
内容的提问来源于stack exchange,提问作者Clement

