我正慢慢地为一个非常愚蠢的问题而失去理智。
我有一个socket.io/express应用程序上传到数码海洋作为码头设置。
为了允许https,我使用caddy作为我的Docker设置的一部分,以允许自动https。
我一直试图连接到这个设置通过我的领域和我的本地反应应用程序,生活在本地主机:3000。但我经常会遇到以下错误:
CORS策略阻止从“
”从“https://mediaserver.domain.dev/socket.io/?EIO=3&transport=polling&t=N5BXNK2”访问XMLHttpRequest的“http://localhost:3000”:当请求的凭据模式为“包含”时,响应中的“访问-控制-允许-原产地”标题的值不能是通配符“*”。由XMLHttpRequest发起的请求的凭据模式由withCredentials属性控制。
我知道之前有很多这样的问题,相信我,我几乎所有的人都试过了。
我尝试更改cors中间件的选项,我尝试添加我自己的中间件,特别是设置头,我尝试使用localhost:3000作为origin
但似乎什么都起不到作用。我现在不知道我还能做些什么来解决这个问题。
所以任何帮助都是受欢迎的。
我的停靠撰写文件如下所示:
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我的Caddyfile文件如下:
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);发布于 2020-04-05 18:26:19
您正在尝试使用设置凭据标志并将Access-Control-Allow-Origin设置为any (*)的跨源请求。出于安全原因,这是不允许的。解决这个问题有两种方法。如果不需要发送凭据,请确保凭据标志为false。也就是说,如果您使用的是XMLHttpRequest,请确保withCredentials不是真(默认情况下是假的)。如果您正在使用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。
发布于 2020-04-06 01:30:45
有一种简单的方法可以绕过socket.io连接的CORS错误。默认情况下,socket.io使用几个常规http调用启动每个连接。如果一切顺利,它将转换为webSocket传输(并在webSocket传输上运行socket.io )。这些初始的http呼叫受到CORs的限制。
但是,如果您告诉socket.io立即开始使用webSocket传输,那么您就不会受到CORs的限制。您可以在客户机中这样做:
const socket = io({transports: ['websocket']});即使webSocket连接总是以一个http请求开始,但特定的http请求(具有适当的upgrade头集)不受CORs限制。
这(据我所知)的唯一缺点是,您的代码不会在不支持webSockets的浏览器中运行。那将是一个非常非常旧的浏览器。甚至连IE10 (2012年发布)都支持webSockets,所有现代浏览器至少从2013年开始都支持它们。实际上,我不太清楚为什么socket.io仍然将http轮询作为默认设置,因为在网络上启动每个连接的效率要低得多。无论如何,您可以轻松地使用io({transports: ['websocket']});绕过它。
https://stackoverflow.com/questions/61047220
复制相似问题