我已经按照官方教程在我的NestJS应用程序中启用了CORS,所以我的
main.ts
看起来像下面这样:
import { FastifyAdapter, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter(), { cors: true });
await app.listen(3000);
}
bootstrap();
当我使用
npm run start:dev
运行应用程序时它有效。
但是,当我尝试先使用
npm run webpack
编译应用程序,然后使用 node server.js
运行它时,cors 将不起作用。
来自客户端的 http 请求将失败:
对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问来源 'http://localhost:8000'。响应具有 HTTP 状态代码 404.
尝试使用此处描述的方法https://docs.nestjs.com/techniques/security#cors
const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);
如果您使用 graphql 运行 NestJs,您将遇到一个问题,即 Apollo 服务器将覆盖 CORS 设置请参阅链接。这下面解决了这个问题。我为此浪费了 8 个小时。 :-( 我希望你看到这个而不是那样做。见link和link
GraphQLModule.forRoot({
debug: process.env.NODE_ENV !== 'production',
playground: process.env.NODE_ENV !== 'production',
typePaths: ['./**/*.graphql'],
installSubscriptionHandlers: true,
context: ({req}) => {
return {req};
},
cors: {
credentials: true,
origin: true,
},
}),
然后在您的 main.ts 中:
app.enableCors({
origin: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
});
cors 配置对象的文档在这里:https://github.com/expressjs/cors#configuration-options
我注意到没有人使用数组作为原点,以防万一有人想要一些快速复制意大利面
如果您想知道,我也进行了研究……http 和 https 被认为是不同的,子域或子域也是如此(www.example.com 和 app.example.com)。
app.enableCors({
origin: [
'http://localhost:3000',
'http://example.com',
'http://www.example.com',
'http://app.example.com',
'https://example.com',
'https://www.example.com',
'https://app.example.com',
],
methods: ["GET", "POST"],
credentials: true,
});
我能够通过提供我自己的 origin 函数来让它工作。完整的 enableCors 函数对于 NestJS 或任何 NodeJS 服务器来说就像:
var whitelist = ['https://website.com', 'https://www.website.com'];
app.enableCors({
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
console.log("allowed cors for:", origin)
callback(null, true)
} else {
console.log("blocked cors for:", origin)
callback(new Error('Not allowed by CORS'))
}
},
allowedHeaders: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe',
methods: "GET,PUT,POST,DELETE,UPDATE,OPTIONS",
credentials: true,
});
如果您使用的是 NestJS Express,则还有 appOptions:
const app = await NestFactory.create<NestExpressApplication>(AppModule);
很遗憾知道你也试过:
const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);
它仍然无法正常工作。
确保在您的服务器端启用了cors,它应该是这样的:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
next();
});
还要确保您的浏览器支持cors。如果所有这些仍然不起作用,我建议您下载适用于 Chrome 的Allow-Control-Allow-Origin 扩展程序,它应该可以解决您的问题。
不知何故问题是使用
npm run webpack
编译它。如果我使用 prestart:prod
编译它,那么它就会工作。
感谢@georgii-rychko 通过评论提出建议。
也许您使用以下白名单获得
undefined
in origin。如果您不想阻止 REST tools 或 server-to-server requests,请在 origin 函数中添加 !origin
检查,如下所示:
const whitelist = ['example.com', 'api.example.com'];
app.enableCors({
origin: function (origin, callback) {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
...
});
Bellow 是我的 main.ts,它最终运行良好。
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('hbs');
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
next();
});
app.enableCors({
allowedHeaders:"*",
origin: "*"
});
await app.listen(3000);
}
bootstrap();
直到我意识到
nest start
在我删除我的main.ts
文件时可以毫无问题地运行之前,所有答案都没有用。
检查您的
main.ts
是否真的被调用了。
如果不是,删除 /dist 文件夹应该可以解决问题。
async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.enableCors()
await app.listen(3000);
}
bootstrap();
我必须在 azure 中启用 cors。以防万一有人遇到同样的问题
在生产模式下运行
npm run start:prod
如果你像我一样尝试了以上所有方法但仍然没有用,你可能需要考虑 CORS ANYWHERE ,
我尝试了所有其他答案,但为我找到了以下作品
const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);
谁想要动态地使用 CORS 策略(例如,您将来源存储在数据库中):
app.enableCors({
credentials: true,
origin: async (requestOrigin: string, next: (err: Error | null, origin?: string[]) => void) => {
const origins = await app.get(AppService).getOrigins();
// origins: StaticOrigin = ['https://google.com', 'http://localhost'];
next(null, origins);
},
});
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const PORT = 5000;
const app = await NestFactory.create(AppModule);
app.enableCors({credentials: true, origin: "http://localhost:3000"});
await app.listen(PORT, () => console.log(`Server started`));
}
bootstrap();
而不是“http://localhost:3000”粘贴你的 url 客户端