Rack throwing EOFError (bad content body)

ぃ、小莉子 提交于 2019-12-01 04:39:57

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...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!