2012-06-09 3 views
7

ExpressでNode.jsを使用して既存のWebサイトを書き直しています。Express JSでAjax用のRESTルートをバックボーン専用に設定する

サイトのフロントエンドはバックボーンJSを使用するため、すべての必要なルートをネイティブバックボーン同期に準拠させる必要があります。今や、URLのほとんどはクライアントとバックボーンの同期のために同じです。しかし、彼らはJSONを返す必要があるので、通常のGETでは動作しません。

だから私は考えていますが、そのような.jsonとして骨格中/コレクションのURLをモデル化するために拡張機能を追加することをお勧めだろう、とエクスプレスでは、すべてのルートのためにこれを持っている:

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

if (req.params.id == 'json')よりJSONを送信します。それ以外の場合はHTMLをレンダリングしますか?

さらに良い方法がありますか?助けてください。

答えて

12

すなわちres.format、エクスプレス3.xのコンテンツネゴシエーション機能を使用することですこれを行うには良い方法:

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' }); 
    } 
}); 

あなたのアプローチは、exのためにYammerのもOKです。 http://developer.yammer.com/api/#message-viewing

+0

お返事ありがとうございます。私はres.format()をExpressのドキュメントで見つけられませんでした。しかし、req.is( 'html')またはreq.is( 'json')が見つかりました。どちらか一方はうまくいくはずですが、res.format()は関数の方が良く見え、res.is()の場合はif/elseを使う必要はありません。 –

+0

Express 3.xが新しく、サイトを更新する必要があるので、ドキュメントにはまだ載っていません(これは私が知る限りすぐに起こります)。 – alessioalex

+0

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

6

リクエストにAcceptというヘッダーを使用してください:Accept: application/json JSONを受信する場合は、Accept: text/HTMLをHTMLにします。

+0

これをNode側でどのように設定するのですか? –

+0

標準のJavaScriptテキスト解析技術(正規表現など)を使用して、 'Accept:'で始まるものについて 'req.headers'を調べます。 JSONを要求するユーザーがいる場合はJSON応答を送信し、そうでない場合はHTML応答を送信する方法があります。 – ebohlman

2

「X-Requested-With」ヘッダーがjQueryなどに設定されているかどうかを確認する別の方法もあります。

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アンダースコアは依存性です。

2

正しい方法は、コンテンツネゴシエーションをアプリケーションに実装することです。はい、Express 3.xの機能は、それを行う方法であり、あなたの質問に直接答えを提供しますが、それはルーティングネゴシエーションの責任をルーティングロジックに置くので、それを行う最良の方法だとは思いません。私はコンテンツネゴシエーションをルーティングロジックに入れて、それがsingle responsibilityの原則に従わないので、それが良い場所だとは思わない。

私はコンテンツネゴシエーションを私のblog engineに実装する際に刺すようにしました。あなたを良い方向に導くのに役立つかもしれないレビューを読んでください。要点は、コードがコンテンツネゴシエーションロジックを介してファイルの拡張子を決定することです。次に、ファイル拡張子を使用して、対応するビューファイルを検索し、応答にレンダリングしてクライアントに返します。コンセプトは、コンテンツネゴシエーションごとに、要求された表現で要求されたリソースで応答することです。 routing logicはビューのみを指定しますが、コンテンツネゴシエーションについては考えていません。これはルーティングロジックの外部で発生し、より柔軟な設計が可能になります。

この設計の結果は次のようにリソースの特定の表現を求めることができることである:

http://blog.joeyguerra.com/index.jsonとJSON表現 http://blog.joeyguerra.com/index.phtmlを取得し、部分的(またはHTMLフラグメント)を取得HTML表現 http://blog.joeyguerra.com/index.xmlと取得XML表現。

関連する問題