12888


Rails 3.2 を使っています。  
ajax で get して、hoge.js.erb で処理をしています。

具体的には商品をどんどん追加していき、最後に submit で POST します。  
商品を追加する部分で **稀にサーバが 304 を返す** のですが、200 でも 304 でも画面上での表示は追加された動きになります。  
しかし、 POST 時に 304 が返ってきた商品は欠落(パラメータに含まれない)してしまいます。

考えられる私の案は

  * 304が返ってきたらブラウザ側で描画しないで「エラー発生。もう一度追加してください」的なメッセージ出す
  * ajax_fire_item アクションの時だけサーバ側で 304 を返さず、200 になるような動作にする

です。

ソースを下記に示します。

発火部分の html.erb  

[code]

    function ajax_fire_item(item_id) {
      $.get('<%= root_path -%>bills/ajax_fire_item', {pet_id: <%= @pet.id -%>, item_id: item_id});
    }
    
[/code]

controller  

[code]

    def ajax_fire_item
      @pet = Pet.find(params[:pet_id])
      @master_item = MasterItem.find(params[:item_id])
    end
    
[/code]

ajax_fire_item.js.erb

[code]

    <% form_for([@pet, @pet.bills.build]) do |f|
      fields = f.fields_for(:bill_items, BillItem.new(master_item_id: @master_item.id, quantity: 1), :child_index => Time.now.to_i) do |builder|
        render("bill_item_fields", :f => builder)
      end
      @fields = j fields
    end %>
    var $item = $("<%= @fields -%>");
    $item.appendTo('#item_list');
    
    calcRow($item); // 横計
    reCalc(); // 合計欄
    
[/code]

試しに発火部分の html.erb を以下の様にしましたが、ログには失敗しても 111 が表示されました。

[code]

    function ajax_fire_item(item_id) {
      $.ajax('<%= root_path -%>bills/ajax_fire_item',{
          data: {pet_id: <%= @pet.id -%>, item_id: item_id},
          type: 'GET',
          success: function (data, status, xhr) {
            // 成功処理
            console.log(111);
          },
          error: function (data, status, xhr) {
            // 失敗処理. 304error はココに来る!?
            console.log(222);
          }
        }
      );
    }
    
[/code]


CC BY-SA 3.0
2015-07-31T09:03:22.950
12880
2015-07-31T12:49:53.107
2015-07-31T12:11:14.167
7208
7208
question
javascript ruby-on-rails
「304 Not Modified」をハンドリングしたい


実行していないので、あくまで推測ですが・・・

304 Not modifiedが返って来た場合、キャッシュからビューが生成されるはずです。  
つまり、画面上は304の場合でも品目は追加されていますが、そのHTMLは前回キャッシュされたものになっているかと思われます。要するに以下のコードの部分が一意にならないということです。

[code]

    :child_index => Time.now.to_i
    
[/code]

試しに品目を何個か追加して、304が出た品目のフィールドのnameが他の品目と重複していないか確認してみてください。もし重複していたらそれが原因です。重複パラメータはPOST時にマージされますので。

とりあえずの対応策は、$.getではなく$.ajaxメソッドを使用して、オプションで

[code]

    cache: false
    
[/code]

を指定しておけば、304は発生しなくなると思います。  
<https://stackoverflow.com/questions/8841425/how-to-set-cache-false-in-jquery-
get-call>

（しかし、ややトリッキーな作りになっているような気がしますので、根本的に修正すべきかも。。。）


CC BY-SA 3.0
2015-07-31T12:49:53.107
12888
2015-07-31T12:49:53.107
2017-05-23T12:38:55.250
-1
9608
12880
answer