【问题标题】:no affect on CORS enabling with NESTJS对使用 NESTJS 启用 CORS 没有影响
【发布时间】:2021-11-14 11:37:42
【问题描述】:

我无法启用 CORS 以使用最新的 NestJS 8.0.6 和新的 http + ws 项目进行测试。也就是说,我想在服务器响应中看到Access-Control-Allow-Origin(以便客户端接受它)。这是我的 main.ts,我尝试了 3 种方法:1) 使用选项,2) 使用方法,3) 使用 app.use。它们都不起作用。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { microserviceConfig} from "./msKafkaConfig";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { cors: true}); // DOESN'T WORK
  app.enableCors(); // DOESN'T WORK

  app.connectMicroservice(microserviceConfig);
  await app.startAllMicroservices();

  
  // DOESN'T WORK
  app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS,UPGRADE,CONNECT,TRACE');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
    next();
  });
  
  await app.listen(3000);



}
bootstrap();

如果我们接受所有域,请不要告诉我 CORS (XSForgery) 有多危险。有足够的材料。我很清楚这一点。这是关于 NestJS 没有回复标题中的 Access-Control-Allow-Origin 元素。

浏览器控制台报告:

Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=4&transport=polling&t=Nm4kVQ1' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

在我看到的 chrome header 检查中:

Request URL: http://localhost:3000/socket.io/?EIO=4&transport=polling&t=Nm4kUZ-
Referrer Policy: strict-origin-when-cross-origin
Connection: keep-alive
Content-Length: 97
Content-Type: text/plain; charset=UTF-8
Date: Mon, 20 Sep 2021 19:41:05 GMT
Keep-Alive: timeout=5
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,de-DE;q=0.9,de;q=0.8,en-US;q=0.7,es;q=0.6
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:3000
Origin: http://localhost:4200
Pragma: no-cache
Referer: http://localhost:4200/
sec-ch-ua: "Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
EIO: 4
transport: polling
t: Nm4kUZ-

Referrer Policy: strict-origin-when-cross-origin 有影响吗?

(顺便说一句,通过简单的快速设置就可以正常工作。所以这不可能是我的浏览器的错。)

【问题讨论】:

  • 不是侮辱,而是因为很多人都犯了这个错误,您是否检查了网络控制台中的响应以确定响应的确切内容,而不是在 CORS 错误处停止? 究竟是什么cors错误? websocket如何在这里发挥作用?
  • 我刚刚用curl{ cors: true }app.enableCors() 进行了测试。这两个选项都导致了响应标头Access-Control-Allow-Origin: *。不知道你遇到了什么,但这似乎不是框架的错
  • @KevinB 我不认为 websocket 应该有任何影响。毕竟这只是一个http升级——只是指出来。
  • @JayMcDoniel 是的。我也检查过。 (在添加了 Kafka 生产者和消费者之后,我添加了 CORS。也许我在那里搞砸了)。无论如何,谢谢您的确认。
  • 那个 URL 看起来像一个 Socket.IO 连接 URL。您是否为网关启用了 CORS 选项? @WebsocketGateway({ cors: '*:*' })

标签: node.js websocket nestjs


【解决方案1】:

enableCors{ cors: true } 选项用于 HTTP 服务器(express 或 fastify)。给出的显示 CORS 错误的 URL 来自 socket.io 连接。要为 socket.io 启用 CORS,您需要使用 @WebsocketGateway() 装饰器中的选项,例如

@WebsocketGateway({ cors: '*:*' })
export class FooGateway {}

确保将 websocket cors 的主机和端口都设置为 host:port

【讨论】:

    【解决方案2】:

    我最近遇到了同样的问题
    并将其固定为以下 在 main.ts 中

    in main.ts
    
        // import
        import { NestExpressApplication } from '@nestjs/platform-express';
    
        //in bootstrap() function
        const app = await NestFactory.create<NestExpressApplication>(AppModule);
        app.enableCors();
        app.setGlobalPrefix('/api/v1')
    
    //in your Gateway service 
    
    import { Socket, Server } from 'socket.io';
    import {
        OnGatewayConnection,
        OnGatewayDisconnect,
        OnGatewayInit,
        SubscribeMessage,
        WebSocketGateway,
        WebSocketServer,
    } from "@nestjs/websockets";
    @WebSocketGateway(
        {
            path: "/api/v1/ws",
            serveClient: false,
            cors: {
                origin: `*`
            }
        })
    export class AppGateway
        implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
        
        private logger: Logger = new Logger(AppGateway.name);
    
        ...
        afterInit(server: Server) {
            this.logger.log(`Init`);
        }
    
        handleDisconnect(client: Socket) {
            this.logger.log(`handleDisconnect: ${client.id}`);
            this.wss.socketsLeave(client.id);
        }
    
        handleConnection(client: Socket, ...args: any[]) {
            this.wss.socketsJoin(client.id)
            this.logger.log(`handleConnection: ${client.id}`);
        }
    }
      
    
       //in your client side 
    
     this.socket = io("ws://localhost:3000", 
           {
            path: "/api/v1/ws",
            reconnectionDelayMax: 10000,
           }
    );
    
    // package.json
      "dependencies": { 
      "@nestjs/platform-socket.io": "^8.0.6",
      "@nestjs/platform-express": "^8.0.0",
      "@nestjs/websockets": "^6.1.0"
    },
     "devDependencies": {
      "@types/socket.io": "^3.0.2",
      "@types/ws": "^7.4.7"
    }
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 它可以帮助我解决 cors 问题。
    【解决方案3】:

    我删除或更改了数组中的 transsports 参数。它来自前端

        //FRONTEND FILE
        socket = io(BE_URL, {
          withCredentials: true,
          query: {
            token,
            isUserNew,
          },
          transports: ['websocket', 'polling'], // USE ['polling', 'websocket'] OR DELETED IT
          autoConnect: false,
        });
    
    
    
    //BACKEND FILE
    @WebSocketGateway({
      cors: { credentials: true, methods: ['GET', 'POST'], origin: ['http://host1', 'http://host2']},
      transports: ['polling', 'websocket'],
    })
    

    我读过 - https://socket.io/docs/v3/client-initialization/#transports

    一个可能的缺点是只有在 WebSocket 连接建立失败时才会检查 CORS 配置的有效性。

    我真的希望这个答案可以为您节省一些时间。

    【讨论】:

      猜你喜欢
      • 2020-02-18
      • 2018-11-29
      • 2015-05-06
      • 2020-11-21
      • 2020-03-02
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多