首页 > 解决方案 > 生产中 socket.io 的 CORS 问题(MEAN 堆栈)

问题描述

我正在使用 socket.io,它在开发中运行良好。我正在使用 MEAN Stack,在开发中,套接字连接设置如下:

const port = process.env.PORT || 3000;
const server = http.createServer(app);

const io = require('socket.io')(server, {
   cors: {
      origins: ['http://localhost:4200'],
   },
});

效果很好。

在生产中虽然它不起作用。我正在使用带有反向代理的 Nginx 来为我的 node.js 服务器和我的 Angular 应用程序提供服务。

我将设置更改为此

const app = express();
const port = process.env.PORT || 3000;
const server = http.createServer(app);

const io = require('socket.io')(server, {
   cors: {
      origin: 'http://travelinked.vm.mi.hdm-stuttgart.de',
      methods: ["GET", "POST"]
      credentials: true      
   }
});

但它仍然不起作用。

这是我的 Nginx 配置

server {
    listen 80;

    server_name http://travelinked.vm.mi.hdm-stuttgart.de;

    location / {
        root /var/www/html;
        try_files $uri $uri/ /index.html;
    }    

    location /api {
        rewrite /api/(.*) /$1  break;
        proxy_pass http://141.62.65.110:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

   location /socket.io {
        proxy_pass http://127.0.0.1:3000;
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  }
}

所以我的网站可以在这个网站上找到:http: //travelinked.vm.mi.hdm-stuttgart.de/ 我的后端:http: //travelinked.vm.mi.hdm-stuttgart.de/api

除了 socket.io 之外,一切正常。总是在这里遇到这个问题

在此处输入图像描述

问题是链接错误..api缺少。它应该是这样的,http://141.62.65.110/api/socket.io/?EIO=4&transport=polling&t=Nbwq82Z但我怎样才能添加这个?

编辑:

对于我的前端,我有这个 BASE_URL,它是后端端点的链接

static readonly BASE_URL: string = 'http://141.62.65.110/api';

这是我客户端上的 socket.io 连接

import { io } from 'socket.io-client';

@Injectable()
export class ChatService {
   private socket = io(`${ApiURLStore.BASE_URL}/`, { path: '/api' });
...

EDIT2:似乎 socket.io 建立了连接,但 URL 错误。这是网络的结果

在此处输入图像描述

所以基本上它连接到这个连接? http://141.62.65.110/api/?EIO=4&transport=polling&t=Nbxuxae

我认为正确的应该是这样的:http: //141.62.65.110:3000/api/socket.io/?EIO=4&transport=polling&t= Nbxuxae

我必须更改前端的链接吗?变成这样: private socket = io('http://141.62.65.110:3000/', { path: '/api/socket.io' });

标签: node.jsangularnginxcorsmean

解决方案


问题是/socket.io通常位于节点根中的内容被 CORS 阻止。您需要在 nginx 服务器块内为其指定 CORS 策略。这应该可以解决问题

location /socket.io {
    proxy_pass http://127.0.0.1:3000;
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  }

编辑:你的块内也有rewrite指令/api,它省略了/api/来自 url

EDIT2:在 require() 中指定 socket.io

const io = require("socket.io")({
  path: "/api",
  ...

推荐阅读