我正在使用node和socket.io来编写聊天应用程序。它在Chrome上运行正常但mozilla在启用跨源请求时出错。
阻止跨源请求:同源策略禁止在http://waleedahmad.kd.io:3000/socket.io/?EIO=2&transport=polling&t=1401964309289-2&sid=1OyDavRDf4WErI-VAAAI读取远程资源。这可以通过将资源移动到同一域或启用CORS来解决。
这是启动节点服务器的代码。
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server),
path = require('path');
server.listen(3000);
app.get('/', function(req, res) {
res.sendfile(__dirname + '/public/index.html');
});
在客户端。
var socket = io.connect('//waleedahmad.kd.io:3000/');
HTML页面上的脚本标记。
<script type="text/javascript" src="//waleedahmad.kd.io:3000/socket.io/socket.io.js"></script>
我也在app根目录中使用.htaccess文件。 (waleedahmad.kd.io/node)。
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
答案 0 :(得分:56)
var io = require('socket.io')(server, { origins: '*:*'});
或
io.set('origins', '*:*');
或
io.origins('*:*') // for latest version
仅仅{p> *
并没有让我陷入兔子洞的工作。
答案 1 :(得分:26)
您可以尝试在服务器端设置origins
选项以允许跨源请求:
io.set('origins', 'http://yourdomain.com:80');
此处http://yourdomain.com:80
是您要允许来自的来源。
您可以详细了解origins
格式here
答案 2 :(得分:18)
对于在这里寻找新Socket.io(3.x)的人来说,migration documents很有帮助。
特别是以下代码段:
@code
{
RenderFragment<RenderFragment> userContent
=> context => @<text>Some stuff @context more stuff</text>;
}
答案 3 :(得分:6)
我在上面尝试过,对我没有任何帮助。以下代码来自socket.io documentation,并且有效。
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
答案 4 :(得分:3)
这可能是Firefox的认证问题,不一定是您的CORS有任何问题。 Firefox CORS request giving 'Cross-Origin Request Blocked' despite headers
我遇到了与Socketio和Nodejs在Firefox中抛出CORS错误完全相同的问题。我有* .myNodeSite.com的Certs,但是我引用了Nodejs的LAN IP地址192.168.1.10。 (WAN IP地址也可能会抛出相同的错误。)由于Cert与IP地址引用不匹配,Firefox会抛出该错误。
答案 5 :(得分:3)
我只是想说,在尝试了一堆东西之后,解决了我的CORS问题的只是使用了较旧的socket.io(版本2.2.0)。我的package.json文件现在看起来像这样:
{
"name": "current-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"devStart": "nodemon server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"socket.io": "^2.2.0"
},
"devDependencies": {
"nodemon": "^1.19.0"
}
}
如果以此执行npm install
,您可能会发现尝试使用socket.io时CORS问题消失了。至少对我有用。
答案 6 :(得分:3)
如果您获得io.set not a function
或io.origins not a function
,则可以尝试使用以下表示法:
import express from 'express';
import { Server } from 'socket.io';
const app = express();
const server = app.listen(3000);
const io = new Server(server, { cors: { origin: '*' } });
答案 7 :(得分:3)
我正在使用v2.1.0
,但以上答案均不适合我。
但这确实做到了:
import express from "express";
import http from "http";
const app = express();
const server = http.createServer(app);
const sio = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin, //or the specific origin you want to give access to,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});
sio.on("connection", () => {
console.log("Connected!");
});
server.listen(3000);
答案 8 :(得分:2)
在StakOverflow和其他论坛上阅读了很多子主题之后,我找到了适用的解决方案。此解决方案适用于没有Express 的情况。
这是先决条件。
服务器端
// DEPENDENCIES
var fs = require('fs'),
winston = require('winston'),
path = require('path');
// LOGS
const logger = winston.createLogger({
level : 'info',
format : winston.format.json(),
transports: [
new winston.transports.Console({ level: 'debug' }),
new winston.transports.File({ filename: 'err.log', level: 'err' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
// CONSTANTS
const Port = 9000,
certsPath = '/etc/letsencrypt/live/my.domain.com/';
// STARTING HTTPS SERVER
var server = require('https').createServer({
key: fs.readFileSync(certsPath + 'privkey.pem'),
cert: fs.readFileSync(certsPath + 'cert.pem'),
ca: fs.readFileSync(certsPath + 'chain.pem'),
requestCert: false,
rejectUnauthorized: false
},
(req, res) => {
var filePath = '.' + req.url;
logger.info('FILE ASKED : ' + filePath);
// Default page for visitor calling directly URL
if (filePath == './')
filePath = './index.html';
var extname = path.extname(filePath);
var contentType = 'text/html';
switch (extname) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
contentType = 'image/jpg';
break;
case '.wav':
contentType = 'audio/wav';
break;
}
var headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
'Access-Control-Max-Age': 2592000, // 30 days
'Content-Type': contentType
};
fs.readFile(filePath, function(err, content) {
if (err) {
if(err.code == 'ENOENT'){
fs.readFile('./errpages/404.html', function(err, content) {
res.writeHead(404, headers);
res.end(content, 'utf-8');
});
}
else {
fs.readFile('./errpages/500.html', function(err, content) {
res.writeHead(500, headers);
res.end(content, 'utf-8');
});
}
}
else {
res.writeHead(200, headers);
res.end(content, 'utf-8');
}
});
if (req.method === 'OPTIONS') {
res.writeHead(204, headers);
res.end();
}
}).listen(port);
//OPENING SOCKET
var io = require('socket.io')(server).on('connection', function(s) {
logger.info("SERVER > Socket opened from client");
//... your code here
});
客户侧
<script src="https://my.domain.com:port/js/socket.io.js"></script>
<script>
$(document).ready(function() {
$.socket = io.connect('https://my.domain.com:port', {
secure: true // for SSL
});
//... your code here
});
</script>
答案 9 :(得分:1)
使用socket.io和node.js&React制作聊天应用程序时遇到问题。同样,此问题对于Firefox浏览器而言不是唯一的问题,我在Edge&Chrome中也面临同样的问题。
“跨域请求已被阻止,其他一些资源正在使用该请求...”
然后我将cors下载到项目目录中,并将其放入服务器文件index.js中,如下所示:要下载,只需使用node.js键入命令:
npm install cors
const cors = require('cors');
app.use(cors());
这将允许CORS被文件中的不同资源使用,并允许浏览器中的跨源请求。
答案 10 :(得分:1)
好的,在使用自签名证书进行测试时,我遇到了一些问题,因此我将复制适用于我的设置。如果您不使用自签名证书,则可能不会出现这些问题!
要开始使用取决于您的浏览器的Firefox或Chrome,您可能会遇到其他问题,我将在稍后解释。
首先设置:
客户
// May need to load the client script from a Absolute Path
<script src="https://www.YOURDOMAIN.com/node/node_modules/socket.io-client/dist/socket.io.js"></script>
<script>
var options = {
rememberUpgrade:true,
transports: ['websocket'],
secure:true,
rejectUnauthorized: false
}
var socket = io.connect('https://www.YOURDOMAIN.com:PORT', options);
// Rest of your code here
</script>
服务器
var fs = require('fs');
var options = {
key: fs.readFileSync('/path/to/your/file.pem'),
cert: fs.readFileSync('/path/to/your/file.crt'),
};
var origins = 'https://www.YOURDOMAIN.com:*';
var app = require('https').createServer(options,function(req,res){
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', 'https://www.YOURDOMAIN.com:*');
res.setHeader('Access-Control-Request-Method', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
res.setHeader('Access-Control-Allow-Headers', '*');
if ( req.method === 'OPTIONS' || req.method === 'GET' ) {
res.writeHead(200);
res.end();
return;
}
});
var io = require('socket.io')(app);
app.listen(PORT);
对于开发而言,在客户端使用的选项在生产环境中是可以的,您需要使用该选项:
rejectUnauthorized: false
您很有可能希望将其设置为“ true”
接下来的事情是,如果它是一个自签名证书,则需要在单独的页面/标签中访问服务器,并接受该证书或将其导入到浏览器中。
对于Firefox,我一直收到错误消息
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
对我来说,解决方案是添加以下选项,并在其他页面/选项卡中接受证书。
{
rejectUnauthorized: false
}
在Chrome中,我不得不打开另一个页面并接受证书,但是之后一切正常,而不必添加任何选项。
希望这会有所帮助。
参考文献:
答案 11 :(得分:1)
如果没有任何效果 在运行窗口中运行 window + r
chrome.exe --user-data-dir =“ C:/ Chrome开发者会话” --disable-web-security
使用此方法解决了我的问题,安装cors插件适用于php,node rest apis,但是在我启用cors套接字停止工作时使用socket.io的情况。 我在不同的端口上同时运行
localhost:3001,而ng在localhost:4200上
更新-我现在正在使用npm cors软件包,它像一个魅力一样工作 socket.io也没问题。
像这样添加它
var express = require('express');
var app = express();
var http = require('http').Server(app);
const cors = require('cors');
var bodyParser = require('body-parser');
app.use(cors());
app.options('*', cors());
const auth = require('./routes/auth');
const port = 3004;
http.listen(port, () => {
console.log( `running http at port ${port}`);
});
答案 12 :(得分:0)
我遇到了同样的问题,任何解决方案都对我有用。
原因是我正在使用allowRequest通过我在查询参数中传递的令牌接受或拒绝连接。
我在客户端的查询参数名称中有一个错字,因此连接总是被拒绝,但是浏览器抱怨cors ...
一旦我修正了错字,它就会按预期的方式开始工作,而且我不需要使用任何多余的东西,全局express cors设置就足够了。
因此,如果有什么对您有用,并且您正在使用allowRequest,请检查此函数是否正常运行,因为它引发的错误在浏览器中显示为cors错误。我想除非您要拒绝连接时手动在此处添加cors标头,否则就可以。
答案 13 :(得分:0)
socket.io和socket.io-client使用相同版本修复了我的问题。
答案 14 :(得分:0)
看看这个: Complete Example
服务器:
let exp = require('express');
let app = exp();
//UPDATE: this is seems to be deprecated
//let io = require('socket.io').listen(app.listen(9009));
//New Syntax:
const io = require('socket.io')(app.listen(9009));
app.all('/', function (request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
客户
:<!--LOAD THIS SCRIPT FROM SOMEWHERE-->
<script src="http://127.0.0.1:9009/socket.io/socket.io.js"></script>
<script>
var socket = io("127.0.0.1:9009/", {
"force new connection": true,
"reconnectionAttempts": "Infinity",
"timeout": 10001,
"transports": ["websocket"]
}
);
</script>
我记得很多天以前从stackoverflow答案中得出的结论;但我找不到提及他们的主要链接
答案 15 :(得分:0)
有时在节点服务器停止时会遇到此问题。 因此,请检查您的节点服务器是否正常工作。
然后你可以使用 io.set('origins', 'http://yourdomain.com:PORT_NUMBER');
答案 16 :(得分:0)
我在 easyRTC 中使用了 socket.io 2.4.0 版本,并在 server_ssl.js 中使用了以下代码,这对我有用
io = require("socket.io")(webServer, {
handlePreflightRequest: (req, res) => {
res.writeHead(200, {
"Access-Control-Allow-Origin": req.headers.origin,
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, Host, Authorization",
"Access-Control-Allow-Credentials": true,
"Access-Control-Max-Age":86400
});
res.end();
}
});
答案 17 :(得分:0)
如果您在 Chrome、Safari 和其他浏览器上运行 socket.io 应用程序,但在 Firefox 中仍然遇到 CORS 问题,并且您使用的是自签名证书,那么问题在于 Firefox 不接受自签名证书默认情况下,您必须通过转到 Firefox 的首选项 > 证书 > 查看证书 > 添加例外来添加例外。
如果您不这样做,Firefox 会显示您发布的具有误导性的错误,但在其开发人员工具的深处,您会发现此错误:MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT。这表明 Firefox 根本不接受该证书,因为它是自签名的。
答案 18 :(得分:0)
以下是官方文档中的解决方案:
<块引用>Since Socket.IO v3, you need to explicitly enable Cross-Origin Resource Sharing (CORS).
const io = require("socket.io")(httpServer, {cors: {
origin: "https://example.com", // or "*"
methods: ["GET", "POST"]}});
答案 19 :(得分:0)
const options = {
cors: {
origin:
String(process.env.ORIGINS_STRING) === "ALL"
? true
: String(process.env.ORIGINS_STRING).split(","),
methods: ["GET", "PUT", "POST", "DELETE"],
allowedHeaders: [
"Access-Control-Allow-Headers",
"X-Requested-With",
"X-Access-Token",
"Content-Type",
"Host",
"Accept",
"Connection",
"Cache-Control",
],
credentials: true,
optionsSuccessStatus: 200,
},
};
在 .env 文件中:
ORIGINS_STRING=ALL
或
ORIGINS_STRING=http://localhost:8080,http://localhost:8081
答案 20 :(得分:0)
我只是将 socket.io 的版本从 2.x.x 更新到后端的 4.1.2 并做了同样的事情,即。将前端的 socket.io-client 版本从 2.x.x 更新到 4.1.2 ....它工作了