Node.jsでWebアプリケーションを作成するためにexpressを使用しています。これは私が持っているものを単純化したものです。
var express = require('express');
var jade = require('jade');
var http = require("http");
var app = express();
var server = http.createServer(app);
app.get('/', function(req, res) {
// Prepare the context
res.render('home.jade', context);
});
app.post('/category', function(req, res) {
// Process the data received in req.body
res.redirect('/');
});
私の問題は以下の通りです:
/category
で送信されたデータが検証されないことがわかった場合は、追加のコンテキストを/
ページに渡します。どうすればいいの?リダイレクトはいかなる種類の追加パラメータも許可しないようです。
異なる経路にデータを渡す方法はいくつかあります。最も正しい答えは、もちろん、クエリ文字列です。値が正しく encodeURIComponent および decodeURIComponent であることを確認する必要があります。
app.get('/category', function(req, res) {
var string = encodeURIComponent('something that would break');
res.redirect('/?valid=' + string);
});
req.query
を使用して送信されたパラメータを取得することによって、他の経路でそれを盗むことができます。
app.get('/', function(req, res) {
var passedVariable = req.query.valid;
// Do something with variable
});
より動的な方法では、 url
coreモジュールを使ってクエリ文字列を生成することができます。
const url = require('url');
app.get('/category', function(req, res) {
res.redirect(url.format({
pathname:"/",
query: {
"a": 1,
"b": 2,
"valid":"your string here"
}
}));
});
あなたがすべてのreqクエリ文字列変数をリダイレクトしたいのであればあなたは単にすることができます
res.redirect(url.format({
pathname:"/",
query:req.query,
});
});
もしNode> = 7.xを使っているのなら、 querystring
coreモジュールも使えます。
const querystring = require('querystring');
app.get('/category', function(req, res) {
const query = querystring.stringify({
"a": 1,
"b": 2,
"valid":"your string here"
});
res.redirect('/?' + query);
});
それを行う別の方法は、セッションで何かを設定することです。 ここで設定方法を読むことができます しかし、変数を設定してアクセスするのは次のようなものです。
app.get('/category', function(req, res) {
req.session.valid = true;
res.redirect('/');
});
そして後でリダイレクトの後に...
app.get('/', function(req, res) {
var passedVariable = req.session.valid;
req.session.valid = null; // resets session variable
// Do something
});
Expressの古い機能であるreq.flash
を使用するというオプションもあります。新しいバージョンのExpressでこれを行うには、別のライブラリを使用する必要があります。基本的にそれはあなたが表示され、あなたが次にページに行くときリセットされる変数を設定することを可能にします。ユーザーにエラーを表示するのに便利ですが、やはりデフォルトで削除されています。編集: この機能を追加するライブラリを見つけました。
うまくいけば、Expressアプリケーションで情報をやり取りする方法の一般的なアイデアがわかります。
next()
を使用するためにrouteHandler間でデータをやり取りするための最も簡単な方法は、リダイレクトやセッションを台無しにする必要はありません。必要に応じて、homeCtrl(req,res)
の代わりにnext()
を呼び出し、req
とres
を渡すこともできます。
var express = require('express');
var jade = require('jade');
var http = require("http");
var app = express();
var server = http.createServer(app);
/////////////
// Routing //
/////////////
// Move route middleware into named
// functions
function homeCtrl(req, res) {
// Prepare the context
var context = req.dataProcessed;
res.render('home.jade', context);
}
function categoryCtrl(req, res, next) {
// Process the data received in req.body
// instead of res.redirect('/');
req.dataProcessed = somethingYouDid;
return next();
// optionally - Same effect
// accept no need to define homeCtrl
// as the last piece of middleware
// return homeCtrl(req, res, next);
}
app.get('/', homeCtrl);
app.post('/category', categoryCtrl, homeCtrl);
以下の理由から、提供されているソリューションのどれも実際には要件を満たしていないため、別のソリューションを探す必要がありました。
クエリ文字列 :URLはユーザーによって共有される可能性があるため、クエリ文字列を使用したくない場合があります。また、クエリパラメータが別のユーザーにとって意味がない場合もあります。たとえば、?error=sessionExpired
などのエラーは、誤って他のユーザーに表示されることはありません。
req.session :これには express-session 依存関係が必要なため、req.session
を使用したくない場合があります。これには、セッションストア(MongoDBなど)の設定が含まれます。まったく、または多分あなたは既にカスタムセッションストアソリューションを使用しています。
next() :これは基本的に新しいページを元のURLの下に表示するだけなので、next()
やnext("router")
を使用したくない場合があります。転送/書き換えのような新しいURLへのリダイレクトではありません。受け入れられないかもしれません。
それで、これは私の4番目の解決策で、これまでの問題のどれにも悩まされていません。基本的にそれはあなたが最初に cookie-parser をインストールしなければならない一時的なクッキーの使用を含みます。明らかにこれはクッキーが有効になっている場合に限られた量のデータでのみ機能することを意味します。
実装例:
var cookieParser = require("cookie-parser");
app.use(cookieParser());
app.get("/", function(req, res) {
var context = req.cookies["context"];
res.clearCookie("context", { httpOnly: true });
res.render("home.jade", context); // Here context is just a string, you will have to provide a valid context for your template engine
});
app.post("/category", function(req, res) {
res.cookie("context", "myContext", { httpOnly: true });
res.redirect("/");
}
これは私が他の依存関係を使わずに提案するものです。ただnodeとexpressを使い、app.localsを使ってください、これは例です:
app.get("/", function(req, res) {
var context = req.app.locals.specialContext;
req.app.locals.specialContext = null;
res.render("home.jade", context);
// or if you are using ejs
res.render("home", {context: context});
});
function middleware(req, res, next) {
req.app.locals.specialContext = * your context goes here *
res.redirect("/");
}
クエリ文字列を介して、小さい値のキー/値ペアデータを渡すことができます。
res.redirect('/?error=denied');
そしてホームページ上のjavascriptがそれにアクセスし、それに応じてその振る舞いを調整することができます。
/category
をブラウザのアドレスバーのURLとして使用しても構わない場合は、リダイレクトする代わりに直接レンダリングすることができます。古いWebフレームワークでは直接応答するのが困難だったため、私見は何度も人がリダイレクトを使用しますが、表現は簡単です。
app.post('/category', function(req, res) {
// Process the data received in req.body
res.render('home.jade', {error: 'denied'});
});
@ Dropped.on.Capricaがコメントしたように、AJAXを使用すると、URLの変更の心配がなくなります。
解決策の1つは、ボディパーサーミドルウェアであり、データをJSONオブジェクトとして渡します。
var express = require('express');
var jade = require('jade');
var http = require("http");
const bodyParser = require('body-parser') //requiring body parser
var app = express();
var server = http.createServer(app);
app.get('/', function(req, res) {
// Prepare the context
res.render('home.jade', context);
});
app.post('/category', function(req, res) {
// Process the data received in req.body
//pass the data as an json object
res.redirect('/', { data: data });
});
このデータオブジェクトは、この'/'
パスを通じてアクセスされるページで使用できます。