首页 > 解决方案 > 由于 CORS 错误,Socket.io 和 express 应用程序无法连接:“'Access-Control-Allow-Origin' 标头的值不能是通配符 '*'”

问题描述

我正在慢慢地因为我遇到的一个非常愚蠢的问题而失去理智。

我有一个 socket.io/express 应用程序作为 Docker 设置上传到 Digital Ocean。

为了允许 https,我使用 caddy 作为我的 Docker 设置的一部分,以允许自动 https。

我一直在尝试通过我的域和位于 localhost:3000 上的本地 React 应用程序连接到此设置。但我不断收到以下错误:

从源“ http://localhost:3000 ”访问位于“ https://mediaserver.domain.dev/socket.io/?EIO=3&transport=polling&t=N5BXNK2 ”的 XMLHttpRequest已被 CORS 策略阻止:当请求的凭据模式为“包含”时,响应中的“Access-Control-Allow-Origin”标头不得为通配符“*”。XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。

我知道之前有很多关于这个的问题,当我说我几乎尝试了所有这些问题时,相信我。

但似乎没有任何效果。我目前不知道我还能做些什么来解决这个问题。

因此,欢迎任何帮助。

我的 docker-compose 文件如下所示:

version: '3.6'
services:
  media-server:
    build:
      dockerfile: Dockerfile
      context: ./
    ports:
    - "8080:5000"
    expose: 
      - "5000"
  caddy:
    image: abiosoft/caddy:0.11.0
    depends_on:
      - "media-server"
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /root/Caddyfile:/etc/Caddyfile
      - /root/.caddy:/root/.caddy

我的球童文件如下:

https://mediaserver.domain.dev {
  proxy / http://media-server:8080 {
    websocket
    transparent
  }
  cors
}

我的服务器设置如下所示:

import cors from 'cors';
import express from 'express';
import socket from 'socket.io';

import { intialiseWebSocketConnection } from './socketio';

const app = express();

app.use(cors());

const server = app.listen(5000, function () {
  console.log('Server is connectedd on *:5000');
});

const io = socket.listen(server);

intialiseWebSocketConnection(io);

标签: javascriptdockerexpresssocket.iocors

解决方案


Access-Control-Allow-Origin您正在尝试使用设置了凭据标志并将设置为任何 (*)来发出跨域请求。出于安全原因,这是不允许的。有两种方法可以解决问题。如果您不需要发送凭据,请确保凭据标志为 false。也就是说,如果您使用的是XMLHttpRequestmake sure withCredentialsis not true (默认情况下为 false)。如果您正在使用,请Fetch API确保Request.credentials设置为"omit".

如果您出于某种原因确实需要发送凭据,则必须Access-Control-Allow-Origin在服务器的响应中将 设置为您向服务器发送请求的来源,而不是任何 (*)。要弄清楚您的来源是什么,只需检查Origin您发送到服务器的请求中的标头设置。

默认cors()设置Access-Control-Allow-Origin为 *. 尝试将其更改为:

cors({
    origin: "http://localhost:3000",
    credentials: true
});

另请注意,Chrome 不支持localhost作为来源。为了解决这个问题,您可以--disable-web-security在开发期间使用该标志启动 Chrome。


推荐阅读