jquery不会在$ .ajax上为rails标准REST DELETE答案调用成功方法

san*_*rew 58 rest jquery ruby-on-rails

可能这样的问题不是新的,但我没有发现任何类似的东西.我有这样的jQuery代码:

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

我的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
Run Code Online (Sandbox Code Playgroud)

这很有效.

但是当我使用以下内容(由标准生成)时,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
Run Code Online (Sandbox Code Playgroud)

测试下rails 3.0.3,jQuery 1.4.2Firefox 3.6.13.
Firebug说,在这两种情况下都会触发查询并返回200 OK,在这两种情况下都会删除项目.但在第二种情况下,不会调用回调.

REST中是否存在显着差异,是否有通过使用scaffolded控制器来利用jQuery的方法?

mtj*_*hax 73

我碰过这几次,答案看似简单.

您正在使用dataType : 'json'$ .ajax调用,因此jQuery期待JSON响应.使用head :okRails返回包含单个空格的响应(http://github.com/rails/rails/issues/1742),jQuery不接受该响应作为有效的JSON.

因此,如果你真的希望得到一个错误或一个200 OK的标题,只需dataType : 'html'在你的请求中设置并且它应该工作(如果你没有设置dataType,jQuery将尝试猜测基于响应头的类型,等,仍然可以猜json,在这种情况下,你仍然有这个问题).如果你真的希望得到JSON,而不是使用head :ok带有JSON的渲染(见注释),或者只是head :no_content按照@Waseem的建议使用

  • 在我通过以下方式返回哈希值之前没有为我工作:json as so":json => {'message'=>'delete completed'}" (5认同)
  • 更好的方法是使用`head:no_content`.请参阅http://stackoverflow.com/a/12751298/100466和https://github.com/rails/rails/issues/1742 (2认同)

Nei*_*kar 6

GearHead是正确的,除了jQuery解析器实际上足够聪明,现在将空字符串响应视为null而不是尝试解析它.

但是,如果您有时会收到json并且有时会收到head回复的电话,并且您无法访问服务器或者不想更改所有head呼叫,则可以执行以下备用解决方案:

问题是当你使用Rails时会发送一个空格作为空响应head(参见这里:如何在rails中返回真正的空体?即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 );
    }
Run Code Online (Sandbox Code Playgroud)

如您所见,jQuery 修剪数据之前测试数据是否为空字符串.然后尝试JSON.parse("")在控制台中看到的结果是错误,通过catch语句触发ajax错误回调.

有一个简单的解决方案.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))
    }
  }
})
Run Code Online (Sandbox Code Playgroud)