2012-06-09 8 views
7

Tôi đang viết lại một trang web hiện có bằng cách sử dụng Node.js với Express.Thiết lập các tuyến REST trong Express JS cho Ajax chỉ để sử dụng với Backbone

Mặt trước của trang web sẽ sử dụng Backbone JS và do đó tôi cần phải có tất cả các tuyến đường cần thiết tuân thủ đồng bộ hóa Backbone gốc. Bây giờ hầu hết các URL của khách hàng và cho Backbone đồng bộ sẽ giống nhau. Nhưng chúng sẽ không hoạt động với GET bình thường vì chúng cần trả về JSON.

Vì vậy, tôi nghĩ, nó sẽ là một ý tưởng tốt để thêm phần mở rộng để dựng mô hình URL/Bộ sưu tập trong Backbone, chẳng hạn như .json, và trong Express để có điều này cho tất cả các tuyến đường:

app.get('/p/:topCategory/:category/:product.:format', function(req, res) { ... }); 

đâu if (req.params.id == 'json') hơn chúng tôi gửi JSON, nếu không chúng tôi sẽ hiển thị HTML?

Hoặc có cách tiếp cận tốt hơn không? Hãy giúp tôi.

Trả lời

12

Cách tốt hơn để làm điều này sẽ được sử dụng tính năng đàm phán nội dung trong tốc 3.x, cụ thể là res.format:

https://github.com/visionmedia/express/blob/master/lib/response.js#L299-378

res.format({ 
    text: function(){ 
    res.send('hey'); 
    }, 

    html: function(){ 
    res.send('<p>hey</p>'); 
    }, 

    json: function(){ 
    res.send({ message: 'hey' }); 
    } 
}); 

Bạn tiếp cận cũng là ok, Yammer cho ex. đang sử dụng cùng một cách tiếp cận: http://developer.yammer.com/api/#message-viewing

+0

Cảm ơn bạn đã trả lời. Tuy nhiên, tôi không tìm thấy res.format() trong tài liệu Express. Nhưng tôi tìm thấy req.is ('html') hoặc req.is ('json'). Tôi đoán một trong hai nên làm việc nhưng res.format() trông tốt hơn như là chức năng của nó và tôi không cần phải sử dụng nếu/else nếu cho res.is(). –

+0

Nó không có trong tài liệu vì Express 3.x là mới và trang web cần phải được cập nhật (điều đó sẽ xảy ra rất sớm như xa như tôi biết). – alessioalex

+0

voilà: http://expressjs.com/api.html#res.format – UpTheCreek

6

Sử dụng các tiêu đề Accept trong yêu cầu của bạn: Accept: application/json nếu bạn muốn nhận JSON, Accept: text/HTML nếu bạn muốn HTML.

+0

Và làm cách nào để thiết lập điều này ở phía bên Node? –

+0

Bạn sử dụng các kỹ thuật phân tích cú pháp văn bản JavaScript chuẩn (biểu thức chính quy, v.v.) để xem qua 'req.headers' cho bất kỳ thứ gì bắt đầu bằng' Accept: '. Cách tôi sẽ làm là gửi một câu trả lời JSON nếu bất kỳ ai trong số họ yêu cầu JSON và phản hồi HTML nếu không có ai trong số đó. – ebohlman

2

Một giải pháp thay thế cũng kiểm tra xem tiêu đề "X-Requested-With" đã được đặt cho jQuery và cộng sự chưa.

var onlyAllowJsonRequests = function (req, res, next) { 

    var acceptJson = (req.accepted.length && _.any(req.accepted, function (acc) { return acc.value.indexOf("json") !== -1 })); 

    // also check that "X-Requested-With": "XMLHttpRequest" header is set 
    if (acceptJson && (req.xhr === true)) { 
     next(); 
    } else { 
     res.send(406, "Not Acceptable"); 
    } 
}; 

app.use(onlyAllowJsonRequests); 

NB gạch dưới là dấu hiệu.

2

Tôi nghĩ rằng cách chính xác để thực hiện việc này là triển khai thương lượng nội dung vào ứng dụng của bạn. Yeah, Express 3.x cơ sở là một cách để làm điều đó và cung cấp một câu trả lời trực tiếp cho câu hỏi của bạn, nhưng tôi không nghĩ rằng đó là cách tốt nhất để làm điều đó bởi vì nó đặt trách nhiệm đàm phán nội dung trong logic định tuyến. Tôi không nghĩ rằng đó là một nơi tốt cho nó bởi vì nó không tuân thủ nguyên tắc single responsibility, khi đặt đàm phán nội dung trong logic định tuyến.

Tôi đã tạm dừng triển khai đàm phán nội dung trong số blog engine; xem xét có thể giúp hướng dẫn bạn theo một hướng tốt. Gist là mã xác định phần mở rộng tập tin thông qua đàm phán nội dung logic. Sau đó, với phần mở rộng tập tin, nó muốn tìm tập tin xem tương ứng, đưa nó vào một phản ứng và gửi nó trở lại cho khách hàng. Ý tưởng là nó phản hồi với tài nguyên được yêu cầu trong biểu diễn được yêu cầu cho mỗi thương lượng nội dung. routing logic chỉ chỉ định chế độ xem nhưng không có ý tưởng về thương lượng nội dung. Điều đó xảy ra bên ngoài logic định tuyến để tạo ra một thiết kế linh hoạt hơn.

Kết quả của thiết kế này là khả năng yêu cầu một đại diện cụ thể của tài nguyên như:

http://blog.joeyguerra.com/index.json và có được một đại diện JSON http://blog.joeyguerra.com/index.phtml và nhận được một phần (hoặc một đoạn HTML) HTML đại diện http://blog.joeyguerra.com/index.xml và nhận được một biểu diễn XML.