jquery 不会在 $.ajax 上为 rails 标准 REST DELETE 答案调用成功方法
Posted
技术标签:
【中文标题】jquery 不会在 $.ajax 上为 rails 标准 REST DELETE 答案调用成功方法【英文标题】:jquery doesn't call success method on $.ajax for rails standard REST DELETE answer 【发布时间】:2011-06-15 01:24:13 【问题描述】:可能这样的问题并不新鲜,但我没有找到类似的东西。我有这样的 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?
【问题讨论】:
两个请求是否都返回了有效的 JSON?你可以用 Charles 嗅探一下,或者用 curl 手动击打它们,看看会发生什么? 您的网址中缺少引号,.. 以防万一。 在我为问题准备代码时出现了缺少的 qoute :) dorkitude,据我所知,在第二种方式中它完全返回空答案,只有 200 OK 标头,这是推荐的 REST 方式。第一种方法返回有效的 JSON,但不建议将此类答案用于资源删除 REST 请求。 这个骗子有一个很好的答案,***.com/questions/12407328/… 【参考方案1】:我遇到过几次,答案看似简单。
您在 $.ajax 调用中使用了dataType : 'json'
,因此 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 有效的内容(请参阅 cmets),或者按照 @Waseem 的建议使用 head :no_content
【讨论】:
在这种情况下你会怎么做才能返回失败? 更好的方法是使用head :no_content
。见***.com/a/12751298/100466 和github.com/rails/rails/issues/1742
我遇到了类似的问题,因为 Rails 表单 (simple_form) 中缺少数据类型。以为我会交叉引用这个线程***.com/questions/10839771/… 由<%= simple_form_for @book, :html => :'data-type' => :json, :remote => true do |f| %>
解决
在我通过 :json 返回哈希之前对我不起作用 ":json => 'message' => 'delete completed' "
与@AshBlue 一样,将字符串作为JSON 返回不起作用。我最终返回 nil 并返回一个状态码:render json: nil, status: :ok
【参考方案2】:
GearHead 是正确的,只是 jQuery 解析器现在实际上足够聪明,可以将空字符串响应视为 null 而不会尝试解析它。
但是,如果您的呼叫有时会收到 json,有时会收到 head
响应,并且您无权访问服务器或不想更改所有 head
呼叫,您可以执行此替代解决方案:
问题在于,当您使用 head
时,Rails 会发送一个空格作为空响应(请参阅此处:How to return truly empty body in rails? i.e. 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("")
,您可以在控制台中看到这会导致错误,并通过catch
语句触发ajax 错误回调。
有一个简单的解决方法。 jQuery 允许您在请求一种数据类型并返回另一种数据类型时使用转换器。更多详情请看这里:http://api.jquery.com/extending-ajax/
由于 rails head
响应呈现为文本,您可以简单地定义一个文本到 json 转换器,该转换器将在尝试解析响应之前修剪响应。只需添加这个 sn-p:
// deal with rails ' ' empty response
jQuery.ajaxSetup(
converters:
"text json": function (response)
jQuery.parseJSON($.trim(response))
)
【讨论】:
仅供参考,jQuery.parseJSON
只是一个passthrough to JSON.parse
,它会在空字符串上引发异常(“输入意外结束”)。所以这应该明确检查空响应($.trim(response).length == 0
)和return null
。【参考方案3】:
这有时是由旧版本的 jQuery 验证插件引起的。如果您使用此插件,有时会导致此问题。如果适用于您的情况,有一个更新可以解决此问题。
或者,您可以通过以下方式设置错误处理程序来找出问题所在:
$.ajaxSetup()
或 $.ajaxError()
这可能会返回解析错误。较新版本的 jQuery 因对 JSON 解析非常严格而臭名昭著。
【讨论】:
不,我不使用任何 jQuery 插件(除了我自己编写的一些插件,但它们对 ajax 没有影响)。而且我知道,在所描述的情况下,服务器返回空答案,而 jquery 可能无法解析它。我想知道是否有一种很好的方法可以让它与这个 empty 答案一起工作。 我假设任何无法解析的东西,包括空答案都会触发 ajaxError 回调,所以你可以在那里为它设置一个处理程序。以上是关于jquery 不会在 $.ajax 上为 rails 标准 REST DELETE 答案调用成功方法的主要内容,如果未能解决你的问题,请参考以下文章
无法在 ajax jquery 上为 release() 获取 jcrop 对象
jQuery绑定ajax:成功在rails 3应用程序中无法用于新创建的(ajax)项目
jQuery 表单插件 + Ajax 文件上传 + Rails