2013-02-05 187 views
4

我知道在這個主題上有一些討論,但我無法找到我的問題的答案。我在localhost:8020上的Aptana服務器上運行了一個網頁。該頁面上的JavaScript正在擊中我在本地主機上運行的節點服務器:1337。這裏是節點代碼:Socket.io - 訪問控制 - 允許來源不允許來源

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 ......原產地不被訪問控制允許來源允許的」。我的瀏覽器是Chrome。 1.爲什麼我的瀏覽器使用XMLHTTPRequest而不是WebSocket? 2.當我更改標題時,爲什麼會出現Access控制錯誤? 感謝您提前提供的所有幫助。

+0

我一直面臨同樣的問題,它使我瘋狂。你能找到解決方案嗎? – Bitsian

+0

我弄明白了這一點,我需要發佈完整的答案,但它已經有一段時間了,我需要看看我做了什麼。給我一些關於你的具體問題的更多細節。 – jhamm

+1

我也遇到這個問題,並有興趣聽到你的解決方案。我提出的唯一解決方案並不理想,因爲它涉及到在socket.io庫中修改「manager.js」代碼以更改它聲明頭的行['Access-Control-Allow-Origin'] =' *「;一定有更好的方法... – OtherBrotherDarryl

回答

1

需要注意的一件事是,當Access-Control-Allow-Credentials爲true時,不能在Access-Control-Allow-Origin頭中使用'*'值。刪除Access-Control-Allow-Credentials標頭,或將Access-Control-Allow-Origin設置爲請求Origin標頭的值。

2

您的自定義頭文件實際上永遠不會寫入socket.io相關請求。

Socket.IO重寫了http服務器的某些方法。其中之一就是觸發'請求'處理程序。 Socket.IO只允許自己成爲所有請求的主要處理程序。然後它測試請求是否實際上是一個socket.io請求(基於請求的路徑的前綴)。如果它確定它不應該處理給定的請求,它會觸發其他「請求」處理程序。

您可以看到,只需在writeHead調用之前放置一個console.log語句,您就會發現標準輸出中沒有任何內容出現。

source code,看起來socket.io自動設置Access-Control-Allow-Origin標頭與請求的origin標頭的值。我會假設有一種方法可以在客戶端上設置這樣的頭文件。

因此,要澄清一些事情:

您的瀏覽器falsl回XHR輪詢,因爲它不支持WebSockets的或WebSocket的運輸靜靜地失敗

的頭,你爲自己設定在httpServer request事件中永遠不會被髮送,所以它們對源策略沒有任何操作。

解決方案:找到一種方法來設置請求上的origin標頭。在瀏覽客戶端代碼後,我發現沒有證據表明這可以輕鬆完成。

1

根據socket.io文檔,您應該能夠設置傳輸的優先級(也可以跳過一個,如果它產生問題),並直接配置socket.io起源。

io.set('transports', ['websocket', 'xhr-polling', 'jsonp-polling', 'htmlfile', 'flashsocket']); 
io.set('origins', '*:*'); 
相關問題