Ошибка парсера при использовании jQuery-UJS для удаленного link_to в приложении Rails 3: как я могу отладить это? - PullRequest
9 голосов
/ 22 мая 2011

Я пытаюсь заменить содержимое div после нажатия на ссылку, используя Rails 3, remote_link :remote => true и jQuery.

До сих пор я смог заставить контроллер отображать правильныйчастично при ответе с кодом HTTP 200.Я установил несколько обратных вызовов, чтобы найти причину проблемы:

jQuery(function($) {
    $("#follow-link").bind("ajax:before", function() {
        console.log("ajax:before");
    });

    $("#follow-link").bind("ajax:success", function(data, status, xhr) {
        console.log("ajax:success");
    });

    $("#follow-link").bind("ajax:complete", function() {
        console.log("ajax:complete");
    });

    $("#follow-link").bind("ajax:error", function(xhr, status, error) {
        console.log("ajax:error");
        console.log(error);
    });
});

В то время как before и complete запущены, success нет и error выводит "parsererror".Содержимое, которое я получаю, когда проверяю ответ в инструментах разработчика Safari, представляет собой простую строку.

Почему это вызывает ошибку parsererror?Как я могу получить больше информации о причине этой ошибки?

Ответы [ 7 ]

12 голосов
/ 13 июля 2011

Я также получал странные parsererror с, хотя мои удаленные ссылки правильно указывали на действия с :format => :js, а мои действия контроллера правильно использовали respond_to для обслуживания объектов JSON, таких как:

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

В результате решение просто переместило эту строку в мой application.js:

$.ajaxSettings.dataType = "json";

По умолчанию оказалось, что jQuery пытается оценить все ответы как "script", что, я думаю, означает, что это былопытаясь выполнить его как код?Удаление этой строки сразу решило проблему в глобальном масштабе.

5 голосов
/ 15 февраля 2012

Вместо использования глобальной $.ajaxSettings.dataType = 'json'; установка более чистого решения заключается в добавлении атрибута data-type к элементу формы.Удаленные обработчики событий формы передадут это как dataType в вызов jQuery AJAX, например:

form_for @subject, :remote => true, :html => {'data-type' => 'json'}
3 голосов
/ 23 мая 2011

Я собираюсь предложить ответ, потому что комментарии не допускают никакого форматирования. Вот что: Что-то происходит на стороне сервера, и jQuery не получает то, что вы думаете. Вот выдержка из документации jQuery:

ошибка (jqXHR, textStatus, errorThrown) Функция Функция, которая будет вызывается в случае сбоя запроса. Функция получает три аргумента: jqXHR (в jQuery 1.4.x, XMLHttpRequest) объект, строка описывающий тип ошибки, которая произошло и необязательное исключение объект, если таковой возник. Возможный значения для второго аргумента (кроме нуля) "тайм-аут", "ошибка", "abort" и "parsererror". Когда Произошла ошибка HTTP, errorThrown получает текстовую часть Статус HTTP, например «Не найдено» или «Внутренняя ошибка сервера.»

Это означает, что ваш контроллер может отвечать чем-то, кроме ожидаемых данных. В этом контроллере попробуйте:

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

В любом случае, проверьте свои журналы, чтобы убедиться, что то, что вы думаете, происходит на самом деле. Кроме того, напишите тест, чтобы проверить это:

# 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

Хорошо, это хакерская, хрупкая спецификация, но она будет действовать, пока вы не узнаете, где что-то идет не так.

Как только вы это заработаете, все остальное аккуратно встанет на свои места.

1 голос
/ 25 января 2012

вместо format.js используйте format.json

параметр $.ajaxSettings.dataType = 'json'; может вызвать проблемы в других частях вашего кода.

0 голосов
/ 15 октября 2012

Если вы пытаетесь обновить содержимое DIV с помощью обычного вызова JQuery AJAX, используя вывод HTML из действия контроллера rails, вам нужно сообщить JQuery, какой dataType ожидать в ответе, чтобы он не анализировалответите в виде javascript и дайте вам parsererror, который вы описываете.

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

Это будет совместимо с действием контроллера, которое использует блок response_to:

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 голосов
/ 12 марта 2012

Еще один способ решить эту проблему - добавить .js к действию формы (если вы используете генератор ссылок Rails, вы можете добавить: format =>: json). Затем убедитесь, что вы отвечаете на json в вашем контроллере.

Вот пример формы входа, настроенной таким образом:

    <%= 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 %>

В контроллере:

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 голосов
/ 20 сентября 2011

Решением для меня было также заменить формат ответа на «.html» вместо «.js» в контроллере.

Что он делает, это отправляет тип содержимого ответа как «html / text»вместо "html / javascript", и это как-то приемлемо для анализатора ответов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...