web-dev-qa-db-ja.com

Rails ajaxポストでセッションをリロードしない

RailsとjQueryを使用したajaxで非常に奇妙な問題が発生しています(ただし、jQueryに固有のものではないと思います)。

私のRailsアプリケーションはcookieセッションストアを使用しており、セッションでユーザーIDを設定する非常に単純なログインがあります。user_idがセッションで設定されていない場合、ログインにリダイレクトされますこれは問題なく動作します。JQueryGETリクエストも正常に動作します。問題は、jQueryを実行したときですPOST-ブラウザがセッションCookieを送信しました(Firebugとダンプリクエストでこれを確認しました)ログへの.cookies)ですが、セッションは空白です。つまり、セッションは{}です。

私は私のapplication.jsでこれをやっています:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

そしてこれが私のサンプル投稿です:

$.post('/test/1', { _method: 'delete' }, null, 'json');

これは、このコントローラーメソッド(_method:delete)に到達する必要があります。

def destroy
  respond_to do |format|
    format.json { render :json => { :destroyed => 'ok' }.to_json }
  end
end

ログを見てFirebugを使用すると、ajaxポストが発生したときにリクエストヘッダーで正しいCookie値が送信されていることを確認できますが、ある時点でRailsがこの値を失い、セッションなので、ログインページにリダイレクトされ、メソッドに到達することはありません。

私はこれをデバッグするために考えられるすべてのものを試しましたが、これはRailsのバグの可能性があるという考えに近づいています。私はRails 3.0.4とjQuery 1.5を使用している場合、それが役立つ場合。通常の(つまり非Ajax)getおよびpostリクエストが機能し、ajax getリクエストが機能しないことは非常に奇妙です問題、それはそうではないajax投稿だけです。

これを修正するための助けがあれば大歓迎です!

どうもありがとう、
デイブ

62

何が起こっているのかをうまく理解できたので、私は自分の質問に答えます。他の人に役立つ場合に備えて、ここに投稿します!

さらに調査した後、想定されたコードがCSRFトークンを使用してリクエストヘッダーを設定するコードではないことがわかりました。これは元のコードでした:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

何が起こっていたかというと、このコードはヘッダーを設定していなかった、RailsがAjaxリクエストを受信して​​いた、トークンが一致せず、セッションをリセットしていた。 :InvalidAuthenticityTokenエラー(エラーが発生した場合は、これを先にキャッチしたと思います...まあ)Rails 3.0.4)なので、静かにセッションをリセットします。

ヘッダーでトークンを送信するには、これを行う必要があります(多くの場合 このすばらしいブログ投稿 のおかげです):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
}); 

そして今、それはすべて正常に機能します。いいですね。

113

別のケースを見つけました:

アプリケーションレイアウトファイルに「csrf_meta_tag」を設定しましたか?

私の場合、そのタグを設定しなかったため、同じ問題が発生しました。

そして、app/views/layouts/application.html.erbでcsrf_meta_tagを設定した後、すべてが正常に動作します!

最後に、根本的な原因を見つけてくれてありがとう!どうもありがとうございます

それが、3.0シリーズの official jquery-ujs Rails adapter の目的です。ただし、Railsバージョンをアップグレードする場合は、常に最新の状態に保つ必要があります。

私にとって、3.0.3から3.0.8.rc4へのアップグレードは、リンクされたリポジトリからsrc/Rails.jsファイルを手動でフェッチすることも意味しました。

Rails 3.1がついにjQueryへの切り替えを行ったため、Railsを更新するとき(および3.1の組み込みアセットパイプラインを使用するとき)は、jquery-Rails gemを介して将来的に自動更新されるはずです)

0
TheDeadSerious