Socket.io + Node.js Запрос на перекрестный запрос заблокирован
Я использую node и socket.io для написания приложения чата. Он отлично работает на Chrome, но mozilla дает ошибку, чтобы разрешить запросы Cross-Origin.
Запрос на перекрестный запрос заблокирован: политика одинакового происхождения запрещает чтение удаленного ресурса http://waleedahmad.kd.io:3000/socket.io/?EIO=2&transport=polling&t=1401964309289-2&sid=1OyDavRDf4WErI-VAAAI. Это можно устранить, переместив ресурс в тот же домен или включив CORS.
Здесь мой код для запуска сервера node.
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/');
Script на странице HTML.
<script type="text/javascript" src="//waleedahmad.kd.io:3000/socket.io/socket.io.js"></script>
Я также использую файл .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"
Ответы
Ответ 1
Простое исправление на стороне сервера
var io = require('socket.io')(server, { origins: '*:*'});
или
io.set('origins', '*:*');
или
io.origins('*:*') // for latest version
*
один не работает, что заставило меня кроличьи дыры.
Ответ 2
Вы можете попробовать установить опцию origins
на стороне сервера, чтобы разрешить запросы с кросс-началом:
io.set('origins', 'http://yourdomain.com:80');
Здесь http://yourdomain.com:80
- это источник, из которого вы хотите разрешить запросы.
Подробнее о origins
формате здесь можно прочитать здесь
Ответ 3
Я пытался выше, и у меня ничего не получалось. Следующий код взят из документации по socket.io, и это сработало.
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
Ответ 4
Это может быть проблема с сертификацией с Firefox, не обязательно что-то не так с вашим CORS. Запрос Firefox CORS, дающий запрос на перекрестный запрос заблокирован, несмотря на заголовки
Я столкнулся с тем же вопросом, что и Socketio и Nodejs, бросающие ошибку CORS в Firefox. У меня были сертификаты для *.myNodeSite.com, но я ссылался на IP-адрес LAN 192.168.1.10 для Nodejs. (IP-адрес WAN также может вызывать ту же ошибку.) Поскольку Cert не соответствовал ссылке на IP-адрес, Firefox выбросил эту ошибку.
Ответ 5
Прочитав много статей на 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>
Ответ 6
Я использую 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);
Ответ 7
Если ничего не работает Запустите это в окне запуска окна + г
chrome.exe --user-data-dir = "C: /Chrome dev session" --disable-web-security
Моя проблема решена с помощью этого метода, установка плагина cors работает для php, apis rest rest узла, но в случае socket.io, когда я включаю сокет cors перестал работать. я работаю как на разных портах
localhost: 3001 и нг на localhost: 4200
UPDATE-- я сейчас использую пакет 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}');
});
Ответ 8
Хорошо, у меня были некоторые проблемы, заставляющие это работать с использованием самоподписанного сертификата для тестирования, поэтому я собираюсь скопировать мою установку, которая работала для меня. Если вы не используете самозаверяющий сертификат, у вас, вероятно, не будет этих проблем, надеюсь!
Для начала, в зависимости от вашего браузера 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
Вы, скорее всего, захотите установить значение "истина"
Следующее, что нужно сделать, если это самозаверяющий сертификат, вам нужно посетить свой сервер на отдельной странице/вкладке и принять сертификат или импортировать его в свой браузер.
Для Firefox я продолжал получать ошибку
MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
Решением для меня было добавить следующие параметры и принять сертификат на другой странице/вкладке.
{
rejectUnauthorized: false
}
В Chrome мне пришлось открыть еще одну страницу и принять сертификат, но после этого все работало без необходимости добавлять какие-либо параметры.
Надеюсь это поможет.
Рекомендации:
https://github.com/theturtle32/WebSocket-Node/issues/259
https://github.com/socketio/engine.io-client#methods