Socket.io+;Node.js跨源请求被阻止
我正在使用node和socket.io编写聊天应用程序。它在Chrome上运行良好,但mozilla在启用跨源请求时出错 已阻止跨源请求:同一源策略不允许读取位于的远程资源。这可以通过将资源移动到同一域或启用CORS来解决 这是我启动节点服务器的代码Socket.io+;Node.js跨源请求被阻止,node.js,sockets,socket.io,cors,Node.js,Sockets,Socket.io,Cors,我正在使用node和socket.io编写聊天应用程序。它在Chrome上运行良好,但mozilla在启用跨源请求时出错 已阻止跨源请求:同一源策略不允许读取位于的远程资源。这可以通过将资源移动到同一域或启用CORS来解决 这是我启动节点服务器的代码 var express = require('express'), app = express(), server = require('http').createServer(app), io = require('so
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>
您可以尝试在服务器端设置
origins
选项以允许跨源请求:
io.set('origins', 'http://yourdomain.com:80');
这里http://yourdomain.com:80
是您希望允许来自的请求的来源
您可以阅读更多关于
源代码
格式这可能是Firefox的认证问题,而不一定是您的CORS有任何问题
我遇到了同样的问题,Socketio和Nodejs在Firefox中抛出CORS错误。我有*.myNodeSite.com的证书,但我引用的是Nodejs的局域网IP地址192.168.1.10。(WAN IP地址也可能引发相同的错误。)由于证书与IP地址引用不匹配,Firefox引发了该错误 简单服务器端修复
注意:不要使用“socketio”软件包。。。使用“socket.io”代替。“socketio”已经过时了。有些用户似乎使用了错误的软件包
socket.io v3
const io = require('socket.io')(server, { origins: '*:*'});
文件:
cors选项:
socket.ioconst io = require('socket.io')(server, { origins: '*:*'});
或
或
*
单靠它是行不通的,这让我陷入了困境。在StakOverflow和其他论坛上读了很多主题后,我找到了适合我的有效解决方案。此解决方案适用于在没有Express的情况下使用
以下是先决条件
- 从套接字将连接到的同一服务器调用js脚本(src=)(而不是CDN或本地调用)
- 确保服务器端和客户端具有相同版本的socket.io
- 所需的节点模块:,和
- 安装让我们加密certbot和/或购买SSL证书
- 之前在客户端声明的jQuery
- UTF-8编码
服务器端
// 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>
客户端
// 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>
$(文档).ready(函数(){
$.socket=io.connect('https://my.domain.com:port', {
secure:true//for SSL
});
//…您的代码在这里
});
我尝试了上述方法,但没有任何效果。下面的代码来自,它工作正常
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
好吧,我在使用自签名证书进行测试时遇到了一些问题,所以我要复制我的设置,它对我有效。如果您不使用自签名证书,您可能不会有这些问题,希望如此 首先,根据您的浏览器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>
对于开发,客户端使用的选项在生产中是可以使用的。您可能需要以下选项:
rejectUnauthorized: false
您很可能希望设置为“true”
接下来,如果是自签名证书,您需要在单独的页面/选项卡中访问服务器,并接受证书或将其导入浏览器
对于Firefox,我不断地得到错误
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
我的解决方案是添加以下选项并在不同的页面/选项卡中接受证书
{
rejectUnauthorized: false
}
在Chrome中,我不得不打开另一个页面并接受证书,但在那之后,一切都很好,不需要添加任何选项
希望这有帮助
参考资料:
我使用的是
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);
我在使用socket.io和node.js制作聊天应用程序时遇到了问题&React。另外,这个问题对于Firefox浏览器来说并不重要,我在Edge和Chrome浏览器中也面临同样的问题 “跨源请求被阻止,并被其他一些资源使用…” 然后我在项目目录中下载cors,并将其放入服务器文件index.js中,如下所示:要下载,只需使用node.js键入command: npm安装cors
这将允许文件中的不同资源使用CORS,并允许浏览器中的跨源请求。我也遇到过同样的问题,任何解决方案都能为我解决 原因是我正在使用allowRequest接受或拒绝连接,使用我在查询参数中传递的令牌 我在客户端的查询参数名称中有一个输入错误,所以连接总是被拒绝,但浏览器抱怨cors 一旦我修正了输入错误,它就开始按预期工作,我不需要使用任何额外的东西,global express cors设置就足够了
因此,如果有任何东西适合您,并且您正在使用allowRequest,请检查此函数是否正常工作,因为它抛出的错误在浏览器中显示为cors错误。除非您在想要拒绝连接时手动在那里添加cors头,否则我猜。如果您正在获取
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: '*' } });
对于任何在这里寻找新的Socket.io(3.x)的人来说,这是非常有用的 特别是这个片段:
const io = require("socket.io")(httpServer, {
cors: {
origin: "https://example.com",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
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>
我只是想说,在尝试了很多东西之后,解决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问题消失了。至少它对我起了作用。对socket.io和socket.io-client使用相同的版本修复了我的问题。看看这个:
服务器:
const io = require("socket.io")(httpServer, {
cors: {
origin: "https://example.com",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
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>
客户端:
const io = require("socket.io")(httpServer, {
cors: {
origin: "https://example.com",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
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>
var socket=io(“127.0.0.1:9009/”{
“强制新连接”:正确,
“重新连接尝试”:“无限”,
“超时”:10001,