jquery не вызывает метод успеха на $ .ajax для rails стандартный ответ REST DELETE - PullRequest
57 голосов
/ 25 января 2011

Может быть, такая проблема не нова, но я не нашел ничего подобного. У меня есть такой код JQuery:

$.ajax({ 
  url : ('/people/'+id), 
  type : 'DELETE', 
  dataType : 'json', 
  success : function(e) {
    table.getItems(currentPage);
  }
});

Мой Rails-контроллер выглядит так:

def destroy
    @person = Person.find(params[:id])
    @person.destroy

    respond_to do |format|
      format.html { redirect_to(people_url) }
      format.json  { render :json => @person, :status => :ok }
    end
end

Это работает.

Но когда я использую следующее (генерируемое стандартом), обратный вызов success не вызывается:

def destroy
    @person = Person.find(params[:id])
    @person.destroy

    respond_to do |format|
      format.html { redirect_to(people_url) }
      format.json  { head :ok }
    end
end

Протестировано под rails 3.0.3, jQuery 1.4.2 и Firefox 3.6.13.
Firebug говорит, что запрос запущен и возвращает 200 OK в обоих случаях, элемент также удален в обоих случаях. Но во втором случае обратный вызов не вызывается.

Есть ли значительная разница в REST и есть ли способ использовать jQuery с помощью контроллера scaffolded?

Ответы [ 3 ]

73 голосов
/ 13 апреля 2011

Я несколько раз сталкивался с этим, и ответ обманчиво прост.

Вы используете dataType : 'json' в своем вызове $ .ajax, поэтому jQuery ожидает ответ JSON.С head :ok Rails возвращает ответ, содержащий один пробел (http://github.com/rails/rails/issues/1742),, который не принимается jQuery в качестве действительного JSON.

Так что если вы действительно ожидаете получить либо ошибку, либо просто 200 OKзаголовок, просто установите dataType : 'html' в вашем запросе, и он должен работать (если вы не установите dataType, jQuery попытается угадать, какой тип основан на заголовках ответа и т. д., и все еще может угадать json, в этом случаеу вас все еще будет эта проблема.) Если вы действительно ожидаете вернуть JSON, вместо использования head :ok отрисовывайте что-то допустимое с JSON (см. комментарии) или просто используйте head :no_content, как предложено @ Waseem

6 голосов
/ 10 октября 2012

GearHead корректен, за исключением того, что парсер jQuery на самом деле достаточно умен, чтобы теперь обрабатывать пустой пустой ответ как ноль, а не пытаться его проанализировать.

Однако, если у вас есть вызовы, которые иногда получают json, а иногда получают ответ head, и у вас нет доступа к серверу или вы не хотите изменять все свои head вызовы, вы можете сделать это альтернативное решение :

Проблема в том, что Rails отправляет один пробел в качестве пустого ответа, когда вы используете head (см. Здесь: Как вернуть действительно пустое тело в рельсах?, Т.е. content-length 0 )

На момент написания этой статьи соответствующие части функции jQuery parseJSON выглядят так:

parseJSON: function( data ) {
    if ( typeof data !== "string" || !data ) {
        return null;
    }

    // Make sure leading/trailing whitespace is removed (IE can't handle it)
    data = jQuery.trim( data );

    // Attempt to parse using the native JSON parser first
    if ( window.JSON && window.JSON.parse ) {
        return window.JSON.parse( data );
    }

Как видите, jQuery проверяет, является ли данные пустой строкой перед тем, как обрезает ее. Затем он пытается JSON.parse(""), который вы видите в консоли, приводит к ошибке, вызывая обратный вызов ошибки ajax с помощью оператора catch.

Есть простое исправление. jQuery позволяет вам использовать конвертеры, когда запрашивается один тип данных, а другой возвращается. Подробнее смотрите здесь: http://api.jquery.com/extending-ajax/

Поскольку ответ rails head отображается как текст, вы можете просто определить конвертер текста в json, который обрежет ответ перед попыткой его проанализировать. Просто добавьте этот фрагмент:

// deal with rails ' ' empty response
jQuery.ajaxSetup({
  converters: {
    "text json": function (response) {
      jQuery.parseJSON($.trim(response))
    }
  }
})
0 голосов
/ 16 марта 2011

Это иногда вызывается старой версией плагина проверки jQuery. Если вы используете этот плагин, это иногда приводит к этой проблеме. Это обновление исправляет это, если оно применимо к вашему делу.

Кроме того, вы можете выяснить, что происходит не так, настроив обработчик ошибок с помощью:

$.ajaxSetup() или $.ajaxError()

Это, вероятно, вернет ошибку разбора. Более новые версии jQuery печально известны своей строгостью в отношении анализа JSON.

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