Nodeとsocket.ioを使用してチャットアプリケーションを記述しています。 Chromeでは正常に動作しますが、mozillaはエラーを出してCross-Origin Requestsを有効にします。
Cross-Origin Request Blocked:Same Origin Policyは、 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>
アプリのルートディレクトリにある.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"
var io = require('socket.io')(server, { origins: '*:*'});
または
io.set('origins', '*:*');
または
io.origins('*:*') // for latest version
*
だけでは機能しません。
サーバー側でorigins
オプションを設定して、クロスオリジンリクエストを許可することができます。
io.set('origins', 'http://yourdomain.com:80');
ここで、http://yourdomain.com:80
は、リクエストを許可するOriginです。
origins
形式の詳細についてはこちらをご覧ください here
私は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 documentation からのもので、動作しました。
io.origins((Origin, callback) => {
if (Origin !== 'https://foo.example.com') {
return callback('Origin not allowed', false);
}
callback(null, true);
});
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>
これはFirefoxの認定問題である可能性がありますが、CORSに問題があるとは限りません。 ヘッダーにも関わらず、 'Cross-Origin Request Blocked'を与えるFirefox CORSリクエスト
SocketioとNodejsがFirefoxでCORSエラーをスローするというまったく同じ問題に直面していました。 * .myNodeSite.comの証明書がありましたが、NodejsのLAN IPアドレス192.168.1.10を参照していました。 (WAN IPアドレスも同じエラーをスローする可能性があります。)CertがIPアドレス参照と一致しなかったため、Firefoxはそのエラーをスローしました。
さて、テスト用に自己署名証明書を使用してこれを機能させるにはいくつかの問題があったので、私のために機能したセットアップをコピーします。自己署名証明書を使用していない場合、おそらくこれらの問題は発生しないでしょう。
ブラウザの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では、別のページを開いて証明書を受け入れる必要がありましたが、その後、オプションを追加しなくてもすべてが正常に機能しました。
お役に立てれば。
参照:
何も機能しない場合は、実行ウィンドウwindow + rでこれを実行します
chrome.exe --user-data-dir = "C:/ Chrome dev session" --disable-web-security
この方法を使用して私の問題は解決しました.corsプラグインのインストールはphp、node rest apisで機能しますが、corsソケットを有効にするとsocket.ioの場合は動作しなくなりました異なるポートで両方を実行しているim
localhost:3001、およびlocalhost:4200のng
更新-私は現在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}`);
});