【问题标题】:NestJS enable cors in productionNestJS 在生产中启用 cors
【发布时间】:2018-11-29 15:31:26
【问题描述】:

我已经在我的 NestJS 应用程序中启用了 CORS,遵循 the official tutorial,所以我的 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”标头。因此,Origin 'http://localhost:8000' 不允许访问。响应的 HTTP 状态代码为 404。

【问题讨论】:

  • 检查浏览器中是否有一些扩展阻止了第 3 个 javascript,例如NoScript 和隐私獾

标签: javascript node.js typescript cors nestjs


【解决方案1】:

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

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

【讨论】:

  • 另外,我有一个问题:为什么要使用 webpack 构建服务器应用程序?通常只使用简单的tsc 调用。
  • 无论如何,只要您可以分享一个重现此问题的示例应用程序 - 这样您可能会更快地获得有关此问题的帮助。
  • 谢谢,但我已经尝试过这个解决方案,不幸的是它不起作用。我使用npm run webpack 为生产进行编译,我猜这是使用 NestJS 的默认方式,不是吗?
  • ShinDarth,看看这个官方的例子。在那里你可以找到应用程序是如何构建的github.com/nestjs/nest/tree/master/sample/10-fastify
  • 这是来自 package.json 的 scripts 部分的编译命令:"prestart:prod": "tsc"。试着玩一下这个例子。如果您有任何问题 - 只需将它们放在此处即可。
【解决方案2】:

很遗憾你也尝试过:

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

【讨论】:

    【解决方案3】:

    不知何故,问题是使用npm run webpack 编译它。如果我使用prestart:prod 编译它,那么它将起作用。

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

    【讨论】:

      【解决方案4】:

      如果您使用 graphql 运行 NestJs,您将遇到 Apollo 服务器将覆盖 CORS 设置 see link 的问题。下面解决了这个问题。我为此浪费了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,
              });
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          也许您会在以下白名单中获得 undefined。如果您不想阻止 REST 工具服务器到服务器请求,请添加 @ 987654322@ 像这样签入原点函数:

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

          【讨论】:

            【解决方案7】:
            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 客户端

            【讨论】:

            • 有什么问题?
            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

              直到我意识到当我删除我的main.ts 文件时nest start 可以正常运行时,所有答案都没有奏效。

              检查您的main.ts 是否实际被调用。

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

              【讨论】:

                猜你喜欢
                • 2020-02-18
                • 2020-01-24
                • 1970-01-01
                • 2021-11-14
                • 2019-03-06
                • 2021-08-09
                • 2022-01-26
                • 2023-01-30
                • 2021-05-03
                相关资源
                最近更新 更多