Parser error when using jQuery-UJS for remote link_to in Rails 3 app: how can I debug this?

后端 未结 7 1950
刺人心
刺人心 2021-02-14 12:55

I\'m trying to replace the content of a div after clicking on a link using Rails 3, remote_link :remote => true and jQuery.

So far, I\'ve been able to ge

相关标签:
7条回答
  • 2021-02-14 13:33

    I'm going to propose an answer because comments don't allow for any formatting. Here is is: Something is happening on the server side and jQuery is not getting what you think it is. Here's an excerpt from the jQuery documentation:

    error(jqXHR, textStatus, errorThrown)Function A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."

    That implies that your controller may be responding with something other than the expected data. In that controller, try:

    Rails.logger.debug render_to_string(:partial => "followings/follow")
    

    In any case, check your logs to make sure what you think is happening really is happening. Also, write a test to verify this:

    # controller spec... modify if using Test::Unit
    it "sends cool javascript" do
      xhr.post :unfollow, :id => 83, :data-method => "delete"
      response.body should == "some known response"
    end
    

    Ok, it's a hacky, brittle spec, but it will do until you know where things are going wrong.

    Once you get this working, everything else will fall neatly into place.

    0 讨论(0)
  • 2021-02-14 13:36

    I was also getting odd parsererrors even though my remote links were correctly pointing to actions with :format => :js and my controller actions were correctly using respond_to to serve up JSON objects like:

    respond_to do |format|
      format.js do
        render :json => {:something => "OK"}
      end
    end
    

    The solution ended up being just dropping this line into my application.js:

    $.ajaxSettings.dataType = "json";
    

    By default, it appeared that jQuery was trying to evaluate all responses as "script", which I guess means it was trying to execute it as code—? Dropping this line in once fixed the issue globally.

    0 讨论(0)
  • 2021-02-14 13:36

    Instead of using the global $.ajaxSettings.dataType = 'json'; setting a cleaner solution is to add a data-type attribute to the form element. The remote form event handlers will pass this through as the dataType to the jQuery AJAX call, e.g:

    form_for @subject, :remote => true, :html => {'data-type' => 'json'}
    
    0 讨论(0)
  • 2021-02-14 13:37

    instead of format.js use format.json

    setting $.ajaxSettings.dataType = 'json'; is liable to cause issues in other parts of your code.

    0 讨论(0)
  • 2021-02-14 13:37

    Another way to solve this is to add .js to the form's action (if you're using a Rails link generator you can add :format => :json). Then make sure you are responding to json in your controller.

    Here's an example of a sign in form configured that way:

        <%= form_for User.new, :url => session_path(:user, :format => :json), :html => {:id => "login-form", :class => "well"}, :remote => :true do |f| %>
          <label>Email</label>
          <%= f.text_field :email %>
          <label>Password</label>
          <%= f.password_field :password %>
          <%= f.hidden_field :remember_me %>
          <%= button_tag "Sign in", :class => "btn", :type => "submit" %><%= image_tag "ajax-loader.gif", :style => "display:none", :id => "login-spinner" %>
        <% end %>
    

    In the controller:

    def create
    respond_to do |format|
      format.html{ super }
      format.json do
       resource = warden.authenticate!(:scope => resource_name, :recall => :failure)
       return sign_in_and_redirect(resource_name, resource)
      end
    end
    end
    
    0 讨论(0)
  • 2021-02-14 13:39

    If you are attempting to update the contents of a DIV using a normal JQuery AJAX call using the HTML output from a rails controller action, you need to tell JQuery what dataType to expect on the response, so that it will not parse the response as javascript and give you the parsererror you describe.

    $.ajax({ url: "/blah", 
      contentType: "text/javascript", dataType: "html",
      beforeSend: function(xhr) {
        xhr.setRequestHeader('Accept', 'text/javascript');    
      }, 
      success: function(data) {
        $('your-div').html(data);
      }
    });
    

    This would then be compatible with a controller action that uses the respond_to block:

    respond_to do |format|
      format.html {
        # This would be a normal render of your template.
      }
      format.js {
        # This would be a render of your template, as HTML, but only for your AJAX requests.
        # We might use this to avoid including the layout of our template.
        render :layout => nil 
      }
    end
    
    0 讨论(0)
提交回复
热议问题