2012-04-09 38 views
11

Tôi đang phát triển một ứng dụng trên máy tính cục bộ của mình. Giao diện người dùng phải được xây dựng với spinejs và backend-api với node.js. cột sống đang chạy trên cổng 9294 và Node.js đang chạy trên cổng 3000. trong cột sống tôi đã thêm vào mô hình của tôi như sau:cột sống, node.js (express) và Access-Control-Allow-Origin

@url: "http:localhost:3000/posts" 

và trong máy chủ nhanh của tôi

app.get('/posts', function(req, res){ 
    console.log("giving ALL the posts"); 
    res.header("Access-Control-Allow-Origin", "*") 
    res.json(posts); 
}); 

Nhưng Tôi luôn nhận được thông báo lỗi sau trong chrome:

XMLHttpRequest cannot load http://localhost:3000/posts. Origin http://localhost:9294 is not allowed by Access-Control-Allow-Origin. 

Tôi phải làm gì để có thể truy cập api đúng cách? Tôi mặc dù thêm tiêu đề trong các phản hồi sẽ khắc phục được sự cố.

+1

Bạn đã kiểm tra tiêu đề phản hồi để xác nhận rằng tiêu đề thực sự đang được đặt chưa? Ngoài ra, jQuery sử dụng lệnh 'OPTIONS' HTTP để phát hiện trước auth; chắc chắn rằng Express cũng đang phản hồi với HTTP Verb đó cũng như là – tkone

+0

một cách trung thực dường như yêu cầu của tôi không bao giờ đến được máy chủ node.js của tôi. Tôi đã thêm một câu lệnh debug trong app.get() TRƯỚC KHI bất cứ thứ gì được gửi đến máy khách. Khi truy cập api của tôi trực tiếp qua url, tôi có thể nhìn thấy câu lệnh nhưng không phải khi truy cập qua cột sống – soupdiver

+0

YOu nên sử dụng thứ gì đó như charles để đảm bảo điều này đang diễn ra. Chúng tôi làm một tấn công cụ miền x ở đây và nó bực bội cho đến khi bạn thấy rằng tiêu đề KHÔNG được đặt. – tkone

Trả lời

16

app.get sẽ chỉ trả lời yêu cầu GET. Nếu trình duyệt đang xem trước nó với yêu cầu OPTIONS, thì tốc độ gửi sẽ gửi một lỗi vì trình duyệt không có bất kỳ người nghe nào cho các yêu cầu đó. Hãy thử thêm mã này ngoài bạn và xem nếu nó hoạt động:

app.options('/posts', function(req, res){ 
    console.log("writing headers only"); 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.end(''); 
}); 

Cũng lưu ý: nếu bạn đang gửi cookie với yêu cầu (withcredentials=true), sau đó các Access-Control-Allow-Origin tiêu đề không thể *, nó phải là chính xác giá trị trong Origin tiêu đề mà trình duyệt sẽ tự động thêm vào yêu cầu ajax như vậy:

res.header("Access-Control-Allow-Origin", req.headers.origin); 

Đây là vì lý do an ninh - nếu bạn đang làm cái gì mà đòi hỏi phải có các tập tin cookie, sau đó nó có nhiều khả năng là bạn sẽ muốn thực sự kiểm tra xem origin có cho phép không trang web ed để tránh CSRF attacks.

+0

cảm ơn anh bạn! Tôi đã không có phương pháp OPTIONS trên màn hình .... làm việc ngay bây giờ :) – soupdiver

15

Phần mềm trung gian này sẽ cho phép CORS sử dụng Express, khóa đang phát hiện yêu cầu preflight OPTIONS và trả về phản hồi để tránh truy vấn cơ sở dữ liệu 404 hoặc trùng lặp. Xem tài nguyên: http://cuppster.com/2012/04/10/cors-middleware-for-node-js-and-express/

var methodOverride = require('method-override'); 
app.use(methodOverride()); 

// ## CORS middleware 
// see: http://stackoverflow.com/questions/7067966/how-to-allow-cors-in-express-nodejs 
var allowCrossDomain = function(req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 

    // intercept OPTIONS method 
    if ('OPTIONS' == req.method) { 
     res.send(200); 
    } 
    else { 
     next(); 
    } 
}; 
app.use(allowCrossDomain); 
+1

Cuối cùng, một trong đó thực sự hoạt động! Cảm ơn! –

+2

methodOverride không còn được gói với Express như phiên bản 4, vì vậy bạn sẽ cần phải bao gồm "ghi đè phương thức" trong package.json của bạn, sau đó thay vì 'app.use (express.methodOverride())', sử dụng 'var methodOverride \t = require ('method-override'); app.use (phương thứcOverride()); ' –

Các vấn đề liên quan