2012-06-24 87 views
86

我試圖在node.js中構建一個Web服務器,該服務器將支持跨域腳本,同時仍提供靜態文件從一個公共目錄。我正在使用express.js,但我不確定如何允許跨域腳本(Access-Control-Allow-Origin: *)。如何在node.js上的express.js框架中啓用跨源資源共享(CORS)

我看到this post,我沒有找到幫助。

var express = require('express') 
    , app = express.createServer(); 

app.get('/', function (req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    next(); 
}); 

app.configure(function() { 
    app.use(express.methodOverride()); 
    app.use(express.bodyParser()); 
    app.use(app.router); 
}); 

app.configure('development', function() { 

    app.use(express.static(__dirname + '/public')); 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function() { 


    var oneYear = 31557600000; 
    // app.use(express.static(__dirname + '/public', { maxAge: oneYear })); 
    app.use(express.static(__dirname + '/public')); 
    app.use(express.errorHandler()); 
}); 

app.listen(8888); 
console.log('express running at http://localhost:%d', 8888); 
+0

注意app.all vs app.get。 這是OPTIONS請求不GET GET –

+0

請參閱[local-web-server](https://github.com/75lb/local-web-server)爲簡單節點的示例,靜態webserver支持CORS – Lloyd

+0

請參閱enable- cors.org/server_apache.html獲取更多信息 – Mostafa

回答

139

退房the example from enable-cors.org

In your ExpressJS app on node.js, do the following with your routes:

app.all('/', function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    next(); 
}); 

app.get('/', function(req, res, next) { 
    // Handle the get for this route 
}); 

app.post('/', function(req, res, next) { 
// Handle the post for this route 
}); 

第一次調用(app.all)應該在你的應用程序中的所有其他路徑之前進行(或者至少你想成爲CORS的那些啓用)。

[編輯]

如果你想標題,以示對靜態文件,以及,試試這個(確保它調用use(express.static())之前是:

app.use(function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    next(); 
}); 

我與您的代碼測試此,並得到了資產的標題從public目錄:

var express = require('express') 
    , app = express.createServer(); 

app.configure(function() { 
    app.use(express.methodOverride()); 
    app.use(express.bodyParser()); 
    app.use(function(req, res, next) { 
     res.header("Access-Control-Allow-Origin", "*"); 
     res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
     next(); 
    }); 
    app.use(app.router); 
}); 

app.configure('development', function() { 
    app.use(express.static(__dirname + '/public')); 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function() { 
    app.use(express.static(__dirname + '/public')); 
    app.use(express.errorHandler()); 
}); 

app.listen(8888); 
console.log('express running at http://localhost:%d', 8888); 

你可以,當然,包裝功能成一個模塊,這樣你就可以做像

// cors.js 

module.exports = function() { 
    return function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    next(); 
    }; 
} 

// server.js 

cors = require('./cors'); 
app.use(cors()); 
+0

嘿,謝謝你的迴應。 我做了你的建議(第一部分,但在請求標題中仍然沒有看到任何不同) 我已經附上上面的當前代碼。 你能解釋一下我可以如何整合你的解決方案的其餘部分嗎? – Guy

+1

我很驚訝,因爲你在'express.static'之前使用'app.router',它不會修改靜態文件的頭文件;無論如何,我已經更新了我的答案,以便它能夠正常工作。 –

+0

謝謝!我看到你是對的。從服務器獲取的資產都帶有請求的標題。 我可能不清楚我的真實問題。 我正在試圖使用get命令對外部服務器進行API調用。這就是我得到錯誤的地方: XMLHttpRequest無法加載http://www.SOMEURL.com。 Access-Control-Allow-Origin不允許源http:// localhost:8888。 – Guy

45

繼@Brandon Tilley解決方案,顯然它起初並不適用於我。不知道爲什麼,也許我使用chrome和不同版本的節點。之後做了一些小小的調整,現在它爲我工作。

app.all('*', function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type'); 
    next(); 
}); 

如果有人遇到與我類似的問題,這可能會有幫助。

+0

注意app.all與app.get。 這是OPTIONS請求不GET GET –

+0

這適用於我(我使用Backbone獲取對象)。我試圖弄清楚它是否可以在IE 8中工作......看起來應該是這樣,但我不知道這個「XDomainRequest」是否需要特殊的東西...... https://developer.mozilla。 org/en-US/docs/HTTP/Access_control_CORS#Browser_compatibility –

+0

如果您正在使用jQuery,這就是您所需要的。 – film42

2

我用這個:

var app = express(); 

app 
.use(function(req, res, next){ 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Headers', 'X-Requested-With'); 
    next(); 
}) 
.options('*', function(req, res, next){ 
    res.end(); 
}) 
; 

h.readFiles('controllers').forEach(function(file){ 
    require('./controllers/' + file)(app); 
}) 
; 

app.listen(port); 
console.log('server listening on port ' + port); 

此代碼假定您的控制器位於controllers目錄。此目錄中的每個文件應該是這樣的:

module.exports = function(app){ 

    app.get('/', function(req, res, next){ 
     res.end('hi'); 
    }); 

} 
-5

一個額外的步驟我應該採取對我的URL轉換從http://localhosthttp://127.0.0.0

+0

你指的是什麼? – Blunderfest

+0

你的意思是http://127.0.0.1?你認爲它有什麼不同? –

1

推薦使用cors Express模塊​​。這允許您將域名列入白名單,允許/限制專門用於路由的域等,

+0

該模塊是否允許您從http:// localhost /?調用服務。 – SuperUberDuper

8

嘗試使用此cors npm模塊。

var cors = require('cors') 

var app = express() 
app.use(cors()) 

該模塊提供了許多功能,以微調CORS爲域名白名單設置,例如,針對特定API等

0

您必須設置Access-Control-Allow-Credentials: true,如果你想通過「資格證書」,使用「曲奇」啓用CORS

app.all('*', function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Credentials', true); 
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type'); 
    next(); 
}); 
相關問題