我遇到了socket.io这个奇怪的问题。我有一个快速应用程序,我在端口5000上运行。我已经像这样配置了socket.io:
const app = require('../index');
const http = require('http');
const server = http.Server(app);
const io = require('socket.io')(server);
io.on('connection', function (socket) {
console.log('User has connected');
socket.emit('connect', {
message: 'Hello World'
});
});
然后我将这段代码导入我的index.js文件中,如下所示:
const express = require('express');
const app = module.exports = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const request = require('request');
const boxRoutes = require('./routes/v1/boxRoutes');
const bidRoutes = require('./routes/v1/bidRoutes');
// use body parser so we can get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));
app.use(bodyParser.json({ limit: '10mb' }));
require('./services/usersClass');
// cors set up
app.use(cors());
app.use(function (req, res, next) {
console.log('Headers Middleware Called');
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'origin, x-requested-with, content-type, accept, x-xsrf-token', 'token');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Request headers you wish to expose
res.setHeader('Access-Control-Expose-Headers', false);
next();
});
// Middleware to authenticate the requests to this service
app.use(function(req, res, next) {
console.log('Auth Middleware Called');
if(!req || !req.headers['authorization']) return res.sendStatus(401);
const token = req.headers['authorization'].split(' ')[1];
request.post(
'http://localhost:4000/api/v1/users/auth',
{
headers: {
'Authorization': `Bearer ${token}`
}
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
const data = JSON.parse(body);
res.locals.user = data.user;
next();
} else {
console.log('Request has failed. Please make sure you are logged in');
res.sendStatus(401);
}
}
);
});
app.use('/api/v1/boxes/', boxRoutes);
app.use('/api/v1/bids/', bidRoutes);
// disable 'powered by'
app.disable('x-powered-by');
app.listen(5000, () => {
console.log('Trading service is running on port 5000');
});
现在,在我的客户端代码中,我尝试在用户登录时建立socket.io连接。每次我尝试连接到服务器时,都会收到以下错误:
无法加载 http://localhost:5000/socket.io/?EIO=3&transport=polling&t=MA_9wXE: 对预检请求的响应未通过访问控制检查: 响应中'Access-Control-Allow-Origin'标头的值必须为 当请求的凭据模式为时,不是通配符'*' '包括'。因此不允许来源“http://localhost:3000” 访问。由...发起的请求的凭据模式 XMLHttpRequest由withCredentials属性控制。
我不明白连接失败的原因。我已将Access-Control-Allow-Origin
配置为我的客户端域,但仍然失败。
答案 0 :(得分:1)
你可以使用cors npm模块。它会解决你的问题。
var cors = require('cors')
var app = express()
app.use(cors({origin: '*'}))
开始' *'意味着允许每个起源。您也可以输入特定来源。
答案 1 :(得分:0)
我以前见过这个问题,但从未见过它表现为交叉问题。您正在创建两个单独的http服务器。一个是制作快速服务器而另一个制作socket.io服务器。您显示的代码实际上只启动快速服务器,并且您没有显示实际启动socket.io服务器的代码。
您可以在此处创建这两个独立的服务器:
const server = http.Server(app); // creates the http server you use for socket.io
app.listen(5000, () => {...}); // creates the http server you use with Express
在app.listen()
内,它创建了自己的新服务器并启动它。您的其他服务器永远不会启动(至少根据您在此处显示的代码)。
当您可能想要做的是使您的socket.io服务器使用与您的快速服务器相同的服务器,然后您应该能够连接正常而没有任何COR问题。
如果要使用app.listen()
,它将返回它创建的server
对象,您需要使用它来初始化socket.io。
如果你想使用其他服务器,那么你需要与你的快速初始化代码共享它,以便它可以使用那个。