NestJS 在生产中启用 cors

问题描述 投票:0回答:17

我已经按照官方教程在我的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.

javascript node.js typescript cors nestjs
17个回答
74
投票

尝试使用此处描述的方法https://docs.nestjs.com/techniques/security#cors

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);

60
投票

如果您使用 graphql 运行 NestJs,您将遇到一个问题,即 Apollo 服务器将覆盖 CORS 设置请参阅链接。这下面解决了这个问题。我为此浪费了 8 个小时。 :-( 我希望你看到这个而不是那样做。见linklink

        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,
        });

21
投票

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,
});

16
投票

我能够通过提供我自己的 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);

8
投票

很遗憾知道你也试过:

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 扩展程序,它应该可以解决您的问题。


5
投票

不知何故问题是使用

npm run webpack
编译它。如果我使用
prestart:prod
编译它,那么它就会工作。

感谢@georgii-rychko 通过评论提出建议。


5
投票

也许您使用以下白名单获得

undefined
in origin。如果您不想阻止 REST toolsserver-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'))
    }
  },
  ...
});

3
投票

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();

0
投票

直到我意识到

nest start
在我删除我的
main.ts
文件时可以毫无问题地运行之前,所有答案都没有用。

检查您的

main.ts
是否真的被调用了。

如果不是,删除 /dist 文件夹应该可以解决问题。


0
投票
async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter());
app.enableCors()
await app.listen(3000); 
}
bootstrap();

0
投票

我必须在 azure 中启用 cors。以防万一有人遇到同样的问题


0
投票

在生产模式下运行

npm run start:prod

0
投票

您需要确保响应将带有正确的标头。 例如,如果你想释放所有来源,那么标题应该是这样的:

访问控制允许来源:*

为此,使用:

const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.enableCors();

你需要在编码前检查这些细节。


0
投票

如果你像我一样尝试了以上所有方法但仍然没有用,你可能需要考虑 CORS ANYWHERE ,

和另一个 Stack Overflow 上的类似答案。


0
投票

我尝试了所有其他答案,但为我找到了以下作品

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);

0
投票

谁想要动态地使用 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);
    },
});

-1
投票
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 客户端

© www.soinside.com 2019 - 2024. All rights reserved.