NestJS 在生产中启用 cors
NestJS enable cors in production
我在 the official tutorial 之后在我的 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 请求将失败并显示:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 404.
尝试使用此处描述的方法https://docs.nestjs.com/techniques/security#cors
const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);
很遗憾知道您也尝试过:
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 supported. If all these still doesn't work, I will advice you download Allow-Control-Allow-Origin Chrome 的扩展,它应该可以解决您的问题。
问题是使用 npm run webpack
编译它。如果我使用 prestart:prod
编译它,那么它将起作用。
感谢@georgii-rychko 通过评论提出建议。
如果您运行使用 graphql 连接 NestJs,您将 运行 遇到 Apollo 服务器将覆盖 CORS 设置的问题 see link. This below fixed the problem. I wasted 8 hrs of my life on this. :-( I hope you see this and you don't do that. see link and 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,
});
我可以通过提供我自己的 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);
也许您使用以下白名单获得 undefined
来源。如果您不想阻止 REST 工具 或 服务器到服务器requests,在原始函数中添加一个 !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'))
}
},
...
});
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 客户端
下面是我的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();
None 的答案一直有效,直到我意识到 nest start
在我删除我的 main.ts
文件时 运行 没有问题。
检查您的 main.ts
是否确实被呼叫。
如果不是,删除 /dist 文件夹应该可以解决问题。
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,
});
async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.enableCors()
await app.listen(3000);
}
bootstrap();
我在 the official tutorial 之后在我的 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 请求将失败并显示:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 404.
尝试使用此处描述的方法https://docs.nestjs.com/techniques/security#cors
const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);
很遗憾知道您也尝试过:
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 supported. If all these still doesn't work, I will advice you download Allow-Control-Allow-Origin Chrome 的扩展,它应该可以解决您的问题。
问题是使用 npm run webpack
编译它。如果我使用 prestart:prod
编译它,那么它将起作用。
感谢@georgii-rychko 通过评论提出建议。
如果您运行使用 graphql 连接 NestJs,您将 运行 遇到 Apollo 服务器将覆盖 CORS 设置的问题 see link. This below fixed the problem. I wasted 8 hrs of my life on this. :-( I hope you see this and you don't do that. see link and 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,
});
我可以通过提供我自己的 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);
也许您使用以下白名单获得 undefined
来源。如果您不想阻止 REST 工具 或 服务器到服务器requests,在原始函数中添加一个 !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'))
}
},
...
});
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 客户端
下面是我的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();
None 的答案一直有效,直到我意识到 nest start
在我删除我的 main.ts
文件时 运行 没有问题。
检查您的 main.ts
是否确实被呼叫。
如果不是,删除 /dist 文件夹应该可以解决问题。
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,
});
async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.enableCors()
await app.listen(3000);
}
bootstrap();