Ich verwende node und socket.io, um eine Chat-Anwendung zu schreiben. Es funktioniert gut in Chrome, aber Mozilla gibt einen Fehler aus, um die Cross-Origin-Anfragen zu aktivieren.
Ursprungsübergreifende Anforderung blockiert: Die gleiche Ursprungsrichtlinie verbietet das Lesen der Remote-Ressource unter http://waleedahmad.kd.io:3000/socket.io/?EIO=2&transport=polling&t=1401964309289-2&sid=1OyDavRDf4WErI-VAAAI . Dies kann behoben werden, indem die Ressource in dieselbe Domäne verschoben oder CORS aktiviert wird.
Hier ist mein Code zum Starten des Knotenservers.
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');
});
Auf der Client-Seite.
var socket = io.connect('//waleedahmad.kd.io:3000/');
Skript-Tag auf der HTML-Seite.
<script type="text/javascript" src="//waleedahmad.kd.io:3000/socket.io/socket.io.js"></script>
Ich verwende auch die .htaccess-Datei im App-Stammverzeichnis. (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"
Antworten:
Einfache serverseitige Korrektur
var io = require('socket.io')(server, { origins: '*:*'});
oder
io.set('origins', '*:*');
oder
io.origins('*:*') // for latest version
*
allein funktioniert nicht, was mich in Kaninchenlöcher geführt hat.quelle
Ich benutze
v2.1.0
und keine der oben genannten Antworten hat für mich funktioniert. Dies tat jedoch: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);
quelle
Sie können versuchen, die
origins
Option auf der Serverseite festzulegen, um Ursprungsübergreifende Anforderungen zuzulassen:io.set('origins', 'http://yourdomain.com:80');
Hier
http://yourdomain.com:80
ist der Ursprung, von dem Sie Anfragen zulassen möchten.Weitere Informationen zum
origins
Format finden Sie hierquelle
Für alle, die hier nach neuem Socket.io (3.x) suchen, sind die Migrationsdokumente ziemlich hilfreich.
Insbesondere dieses Snippet:
const io = require("socket.io")(httpServer, { cors: { origin: "https://example.com", methods: ["GET", "POST"], allowedHeaders: ["my-custom-header"], credentials: true } });
quelle
Ich habe es oben versucht und nichts hat bei mir funktioniert. Der folgende Code stammt aus der Dokumentation zu socket.io und hat funktioniert.
io.origins((origin, callback) => { if (origin !== 'https://foo.example.com') { return callback('origin not allowed', false); } callback(null, true); });
quelle
Nachdem ich viele Subjetcs in StakOverflow und anderen Foren gelesen hatte, fand ich die funktionierende Lösung für mich. Diese Lösung ist für das Arbeiten ohne Express vorgesehen .
Hier sind die Voraussetzungen.
SERVER SEITE
// 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 });
KUNDENSEITE
<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>
quelle
Beim Erstellen einer Chat-App mit socket.io und node.js & React tritt ein Problem auf. Auch dieses Problem ist für den Firefox-Browser nicht platzsparend. Ich habe das gleiche Problem auch in Edge & Chrome.
Dann lade ich cors in das Projektverzeichnis herunter und lege es wie folgt in die Serverdatei index.js: Zum Herunterladen geben Sie einfach den Befehl mit node.js ein:
const cors = require('cors'); app.use(cors());
Dadurch kann CORS von verschiedenen Ressourcen in den Dateien verwendet werden und es kann eine Cross-Origin-Anfrage im Browser gestellt werden.
quelle
Okay, ich hatte einige Probleme damit, dass dies mit einem selbstsignierten Zertifikat zum Testen funktioniert, also werde ich mein Setup kopieren, das für mich funktioniert hat. Wenn Sie kein selbstsigniertes Zertifikat verwenden, werden Sie diese Probleme wahrscheinlich nicht haben, hoffentlich!
Abhängig von Ihrem Browser Firefox oder Chrome können verschiedene Probleme auftreten, die ich Ihnen gleich erläutern werde.
Zuerst das Setup:
Klient
// 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>
Server
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);
Für die Entwicklung sind die auf der Client-Seite verwendeten Optionen in der Produktion in Ordnung. Sie möchten die Option:
rejectUnauthorized: false
Sie möchten höchstwahrscheinlich auf "wahr" setzen.
Wenn es sich um ein selbstsigniertes Zertifikat handelt, müssen Sie Ihren Server auf einer separaten Seite / Registerkarte besuchen und das Zertifikat akzeptieren oder in Ihren Browser importieren.
Für Firefox bekam ich immer wieder den Fehler
Die Lösung für mich bestand darin, die folgenden Optionen hinzuzufügen und das Zertifikat auf einer anderen Seite / Registerkarte zu akzeptieren.
{ rejectUnauthorized: false }
In Chrome musste ich eine andere Seite öffnen und das Zertifikat akzeptieren, aber danach funktionierte alles einwandfrei, ohne dass Optionen hinzugefügt werden mussten.
Hoffe das hilft.
Verweise:
https://github.com/theturtle32/WebSocket-Node/issues/259
https://github.com/socketio/engine.io-client#methods
quelle
Wenn Sie
io.set not a function
oder erhaltenio.origins not a function
, können Sie eine solche Notation versuchen:import express from 'express'; import { Server } from 'socket.io'; const app = express(); const server = app.listen(3000); const io = new Server(server, { cors: { origin: '*' } });
quelle
Dies könnte ein Zertifizierungsproblem mit Firefox sein, nicht unbedingt etwas, das mit Ihrem CORS nicht stimmt. Firefox CORS-Anfrage mit 'Cross-Origin Request Blocked' trotz Headern
Ich hatte genau das gleiche Problem mit Socketio und Nodejs, die in Firefox einen CORS-Fehler auslösten. Ich hatte Zertifikate für * .myNodeSite.com, bezog mich jedoch auf die LAN-IP-Adresse 192.168.1.10 für Nodejs. (Die WAN-IP-Adresse kann ebenfalls denselben Fehler auslösen.) Da das Zertifikat nicht mit der IP-Adressreferenz übereinstimmt, hat Firefox diesen Fehler ausgegeben.
quelle
Ich hatte das gleiche Problem und jede Lösung funktionierte für mich.
Die Ursache war, dass ich allowRequest verwende, um die Verbindung mithilfe eines Tokens zu akzeptieren oder abzulehnen, das ich in einem Abfrageparameter übergebe.
Ich habe einen Tippfehler im Namen des Abfrageparameters auf der Clientseite, daher wurde die Verbindung immer abgelehnt, aber der Browser hat sich über cors beschwert ...
Sobald ich den Tippfehler behoben habe, funktionierte er wie erwartet und ich muss nichts mehr verwenden. Die globalen Express-Cors-Einstellungen reichen aus.
Wenn also etwas für Sie funktioniert und Sie allowRequest verwenden, überprüfen Sie, ob diese Funktion ordnungsgemäß funktioniert, da die von ihr ausgelösten Fehler im Browser als cors-Fehler angezeigt werden. Es sei denn, Sie fügen dort die cors-Header manuell hinzu, wenn Sie die Verbindung ablehnen möchten, denke ich.
quelle