4

SOに関するこのトピックについていくつかの議論があったことは知っていますが、私の質問に対する答えが見つかりません。localhost:8020 で Aptana を使用してサーバー上で Web ページを実行しています。ページの JavaScript が、localhost:1337 で実行しているノード サーバーにアクセスしています。ノードコードは次のとおりです。

var io = require('socket.io');
var http = require('http');
var sys = require('sys');
var json = [];
var server = http.createServer(function (req, res) {

  var headers = {};
  headers["Access-Control-Allow-Origin"] = "*";
  headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
  headers["Access-Control-Allow-Credentials"] = true;
  headers["Access-Control-Max-Age"] = '86400'; // 24 hours
  headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept";
  res.writeHead(200, headers);
  res.end();
});
server.listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
var socket = io.listen(server);
socket.on('connection', function(){
  console.log("Connected");
});

私は常にヘッダーを変更してcorsリクエストを処理しています。私のクライアント側のコードは通常、socket.io の初心者向けのものです。これが私のコードのタグです:

<script src="http://cdn.socket.io/stable/socket.io.js"></script>
    <script>

        // Create SocketIO instance
        var socket = new io.Socket('localhost',{
            port: 1337
        });
        socket.connect();

        // Add a connect listener
        socket.on('connect',function() {
            log('<span style="color:green;">Client has connected to the server!</span>');
        });
        // Add a connect listener
        socket.on('message',function(data) {
            log('Received a message from the server:  ' + data);
        });
        // Add a disconnect listener
        socket.on('disconnect',function() {
            log('<span style="color:red;">The client has disconnected!</span>');
        });

        // Sends a message to the server via sockets
        function sendMessageToServer(message) {
            socket.send(message);
            log('<span style="color:#888">Sending "' + message + '" to the server!</span>');
        }

        // Outputs to console and list
        function log(message) {
            var li = document.createElement('li');
            li.innerHTML = message;
            document.getElementById('message-list').appendChild(li);
        }

コードを実行すると、「XMLHTTPRequest...Origin is not allowed by Access-Control-Allow-Origin」エラーが発生し続けます。私のブラウザはクロムです。1. ブラウザが Websocket ではなく XMLHTTPRequest を使用しているのはなぜですか? 2. ヘッダーを変更しているときにアクセス制御エラーが発生するのはなぜですか? 事前にご協力いただきありがとうございます。

4

3 に答える 3

2

カスタム ヘッダーは、実際には socket.io 関連のリクエストに対して書き込まれることはありません。

Socket.IO は、http サーバーのいくつかのメソッドをオーバーライドします。それらの 1 つは、「リクエスト」ハンドラのトリガーです。Socket.IO は、それ自体がすべての要求のプライマリ ハンドラーになることのみを許可します。次に、リクエストが実際に socket.io リクエストであるかどうかをテストします (リクエストされたパスのプレフィックスに基づいて)。特定のリクエストを処理する必要がないと判断した場合は、他の「リクエスト」ハンドラーをトリガーします。

writeHead 呼び出しの前に console.log ステートメントを配置するだけで、stdout に何も表示されないことがわかります。

ソースコードを読むと、socket.ioがリクエストAccess-Control-Allow-Originのヘッダーの値でヘッダーを自動設定しているようoriginです。クライアントにもそのようなヘッダーを設定する方法があると思います。

したがって、物事を明確にするために:

1 Websocket をサポートしていないか、Websocket トランスポートがサイレントに失敗するため、ブラウザーは xhr-polling に戻ります

2 httpServerrequestイベントで自分で設定したヘッダーは送信されないため、元のポリシーに対してアクションを実行しません。

解決策:originリクエストにヘッダーを設定する方法を見つけてください。クライアント コード全体をクロールした後、これが簡単に実行できるという証拠は見つかりませんでした。

于 2013-02-05T16:12:32.297 に答える
1

注意すべき点の1つは、Access-Control-Allow-Credentialsがtrueの場合、Access-Control-Allow-Originヘッダーで「*」値を使用できないことです。Access-Control-Allow-Credentialsヘッダーを削除するか、Access-Control-Allow-OriginをリクエストのOriginヘッダーの値に設定します。

于 2013-02-05T15:59:36.343 に答える