5

テンプレートにフォームがあり、GETリクエストに応じてレンダリングします。

app.get('/register', function (req, res) {
  res.render('register', {
      title: 'Register'
    , twitterDetails: req.session.twitterDetails
    }
  );
});

POST次に、リクエストでフォームを処理します。

app.post('/register', function (req, res, next) {
  // Generic validation
  req.assert('name', 'Name is empty').notEmpty();
  req.assert('username', 'Username is empty').notEmpty();
  // Email validation
  req.assert('email', 'Email is invalid.').isEmail();
  req.assert('email', 'Email field is empty').notEmpty();
  // Password validation
  req.assert('password', 'Password too short. Must be 6 characters or more.').len(6);
  req.assert('password', 'Passwords do not match.').is(req.body.confirmPassword);
  req.assert('password', 'Password field is empty').notEmpty();
  req.assert('confirmPassword', 'Confirm password field is empty').notEmpty();
  var errors = req.validationErrors(true);
  if (errors) {
    console.log(errors);
    // What do to if there are errors?
  }
  // If there are no errors, continue handling the form…
});

このフォームハンドラーでは、express-validatorモジュールのエラーをチェックしています。これは問題ありませんが、私の質問は、エラーが発生した場合の対処方法です。AFAIK、2つのオプションがあります:

  1. 次のリクエストにエラーを渡すため/registerに使用して、ユーザーをにリダイレクトしますreq.flash
  2. テンプレートを再レンダリングし、エラーをテンプレートに直接渡します

最初のオプションでは、ユーザーをから遠ざけることでフォームデータを失うリスクがありますPOST。使用して入力したデータでフォームをプリエンプトすることもできreq.flashますが、ページが更新されるとこれは表示されなくなります。

2番目のオプションでは、自分自身を繰り返しています。特に、テンプレートに多くの変数を送信する場合は、すべてを繰り返す必要があります。また、すべてのフォームデータをテンプレートに通して、それらの値をフォームに入力する必要があります。

このようなフォームを処理するための正しい手順は何ですか?

4

4 に答える 4

8

オプション1を使用します。これはPOST/リダイレクト/GETパターンと呼ばれ、あらゆる場所で使用されます。

データを失うことを恐れている場合は、セッションを使用してください。それが彼らの目的です。セッション中の状態の維持。

HTTPはステートレスであることを忘れないでください。

于 2012-12-20T07:54:42.030 に答える
2

私の意見では、むしろオプション2を使用する必要があります。

POST / Redirect / GETパターンは、主にユーザーによる送信の成功に適用され、投稿の重複を回避するのに役立ちます。これは、失敗した送信にも使用する必要があるという意味ではありません。

送信に失敗した場合は、別のページにリダイレクトせずに、エラーメッセージを含むフォームを再レンダリングするのが一般的な方法です。

オプション1は、送信の試行が失敗した後にページを更新するときにユーザーが再送信しないという点で、使いやすさをわずかに向上させます。一方、セッションまたはGETパラメータにフォームデータを格納する必要があるため、処理ははるかに複雑です。

つまり、全体として、使いやすさの点ではオプション1がおそらく最高ですが、オプション2は依然として一般的な方法であり、はるかに実用的です。

参照:Post / Redirect / Getパターンでサーバー側のエラーはどのように処理されますか?

于 2014-05-09T10:16:23.120 に答える
1

ここに例があります:

./views/layout.ejs内のページ下部のタグにこれを追加します。

<script>
var app = window.app || {};
app.req = app.req || {};
app.req.err = <%- JSON.stringify(err) %>;
app.req.q = <%- JSON.stringify(q) %>;
</script>

POSTエラーからの実際のデータの例:

app.req.err = {"email":{"param":"email","msg":"Enter email","value":""}};
app.req.q = {"username":"chovy","email":"","password":"somepassword"};

これを行う各POSTにミドルウェアがあります。

  res.locals.q = req.body;
  res.locals.err = false;

エラーが発生した場合は、次のように入力します。./routes/signup.js:

  req.assert('email', 'Enter email').notEmpty().isEmail();
  req.assert('username', 'Enter username').notEmpty().isAlphanumeric().len(3,20);
  req.assert('password', 'Enter password').notEmpty().notContains(' ').len(5,20);

  res.locals.err = req.validationErrors(true);

次に、グローバルクライアント側のjsは、ページが読み込まれるたびにこのルーチンを実行します。これは、基本的にapp.req.errをチェックし、フォームエラーを処理します。

app.utils.form.errors();

関数は次のとおりです。

app.utils.form.errors = function(err){
    err = err || app.req.err;
    app.utils.form.prefill();
    for ( var e in err ) {
        var $field = $('[name='+e+']'),
        $el = $field.parents('p');

        $el.addClass('err');
        $el.append('<span class="msg">'+err[e].msg+'</span>');
    }
};

app.req.qからフォームに事前入力します。

app.utils.form.prefill = function(){
    for ( var param in app.req.q ) {
        var $field = $('[name='+param+']');
        $field.val(app.req.q[param]);
    }
};

このサインアップフォームにアクセスして空白で送信し、ソースを表示すると、実際の動作を確認できます。http : //wishd.me/signupjavascriptはhttp://wishd.me/app.jsにあります。

秘訣は、フォームフィールドにインラインエラーメッセージを表示するための十分なスペースを残すことです。これは、どのフィールドにあるかに関係なく、すべてのエラーが同じように処理されるためです。もちろん、インラインエラーメッセージの位置を変更したり、ラベルを赤に着色したりする可能性のあるcssには、いくつかの例外があります。

http://wishd.me/style.css.errクラスを探します

于 2012-12-20T07:50:44.777 に答える
1

私はexpressjs4.0を使用して、検証後にフォームフィールドに再入力しています。

router.route('/posts/new')
 .get(function(req, res) {
 res.render('posts/new', new Post({}));
});

以下のres.renderの2番目の引数は、ビューにいくつかの変数を設定します。

res.render('posts/new', new Post({}));

私の見解では、フォームフィールドを次のように設定します。

...
<input type="text" name="title" value="<%- post.title %>">
<textarea name="article"><%- post.article %></textarea>
...

このフォームを送信すると、次のようにルーターによってキャッチされます。

router.route('/posts')
  .post(function(req, res) {
    var post = new Post(req.body)
      post.save(function(err) {
       if (err) {
         res.locals.errors = err.errors;
         res.locals.post = post;
         return res.render('posts/new');
       }
      return res.redirect('/posts');
  });
  ...
})

このコード行は、ビューのフォームフィールドをリセットします

res.locals.post = post;

私は誰かがこれが役に立つと思うことを願っています;)

于 2015-01-16T16:35:02.023 に答える