Rack throwing EOFError (bad content body)

后端 未结 1 1189
野趣味
野趣味 2021-01-12 21:40

We\'re using Ruby 2.1.2, Rails 3.2.19 with JQuery 1.11, asset pipeline is not being used (so not using JQuery-ujs, but are using relevant rails.js explicitly). For most user

相关标签:
1条回答
  • 2021-01-12 21:49

    This was finally solved and I'm posting what happened in case it's helpful to others.

    Summary The original code contained an ajaxSubmit (via jquery.form plugin) in the JS which submitted a form (as a POST) with multipart/form-data encoding (so far so good). The rails controller handling the submission processed the data normally and then redirected to a second href (as a GET). The browser (perhaps still processing through the jquery.form plugin before returning to it's success callback handler) received the redirect and retained the multipart/form-data encoding type. When rack received the GET with multipart encoding still specified, it balked because there was no multipart data to parse.

    Sorry, much of this wasn't in evidence in my OP. And it's not clear to me why this worked under an older version of JQuery and the JQuery.form plugin or why it sometimes succeeded under the new JQuery/JQuery.form.

    Solution Refactored the controller to no longer redirect, but rather return a URL (as a text render) for the success callback handler of the original ajaxSubmit. The success handler now then does an AJAX GET on the returned URL thereby leaving the workflow intact but avoiding any multipart encoding on the GET request.

    tl;dr :

    Before the code was ever changed, we had a path involving Jquery.form that went something like this (code example is not meant to be executable, but just as an illustration):

    Ruby view (in HAML for form being submitted):

    = form_for @someObject, html: {:multipart => true, :class => "someformclass"} do |f|
      = f.error_messages
      = hidden_field_tag :submitted, true
      =# some more fields
      %p.submits
        = f.submit "Submit", class: "submit"
    

    Ruby controller:

    class OurController < ApplicationController
      layout false
      before_filter :authenticate_user!
    
      # some other actions
    
      def create
        # some processing
    
        someObject.save
        redirect_to new_feedback_path, :method => :get, :notice => "notice text", status: 303
      end
    
      # some other actions
    end
    

    JS:

    $(document).on('click', '.someformclass .submit', function() {
      ...
      $(this).parents('form').ajaxSubmit({     // uses jquery.form
        ...
        beforeSubmit: function(someargs) {
          ... blah blah
        },
        success: function(responseText) {
          // ... code to display flash message
          if (typeof(window.history.pushState) == 'function') {
            window.history.pushState('html', 'sometext', $.cookie('current_url'));
            matchFiltersClass(window.location.pathname);
          } else {
            window.location.hash = '#!' + $.cookie('current_path');
            matchFiltersClass($.cookie('current_path'));
          }
          $('#main_content').html(responseText);
        }
      });
      return false;
    });
    

    This was refactored as follows (again, just an illustration):

    Ruby view (in HAML for form being submitted): unchanged

    Ruby controller:

    class OurController < ApplicationController
      layout false
      before_filter :authenticate_user!
    
      # some other actions
    
      def create
        # some processing
    
        someObject.save
        flash[:notice] = 'notice text'    # NEW LINE
        render text: new_feedback path, status: accepted  #CHANGED LINE
      end
    
      # some other actions
    end
    

    JS:

    $(document).on('click', '.someformclass .submit', function() {
      ...
      $(this).parents('form').ajaxSubmit({     // uses jquery.form
        ...
        beforeSubmit: function(someargs) {
          ... blah blah
        },
        success: function(responseText) {
          // ... code to display flash message
          $.get(responseText, function(data) {       // NEW LINE
            if (typeof(window.history.pushState) == 'function') {
              window.history.pushState('html', 'sometext', $.cookie('current_url'));
              matchFiltersClass(window.location.pathname);
            } else {
              window.location.hash = '#!' + $.cookie('current_path');
              matchFiltersClass($.cookie('current_path'));
            }
            $('#main_content').html(responseText);
          });       // NEW LINE
        }
      });
      return false;
    });
    

    This solution was found with some help with a local developer (thanks, Dan Axtman!) and not without a fair amount of time in monkey-patched logging in Rack (thanks, Isaac Betesh!). At least I learned something about Rack and monkey patching in the process...

    0 讨论(0)
提交回复
热议问题