我一直在寻找类似的主题,但尽管我读了很多书,但我对responsd_to块的用法仍然有点困惑。
我在客户端使用form_with来执行AJAX请求。在控制器中,我的操作如下:
def create
@role = Role.new(role_params)
respond_to do |format|
if @role.save
format.html { redirect_to url_for(controller: 'roles', action: 'index') }
format.json { render json: { :location => url_for(controller: 'roles', action: 'index') }, status: 302 }
else
format.html { render action: 'new' }
format.json { render json: { :errors => @role.errors }, status: 422 }
end
end
end
我理解responsd_to-bock的方式是,当你发出AJAX请求时,它应该使用json进行回复,如果你发出常规请求,它应该通过html进行回复。这是正确的吗?
在这种情况下,它总是使用format.html进行回复。我已经检查过,如果我把format.json放在第一位(高于format.html(,它确实使用json进行回复。
出了什么问题,或者我错过了什么?
谢谢!
我理解responsd_to bock的方式是,当您制作AJAX时请求,它应该使用json进行回复,如果请求应该使用html进行回复。这是正确的吗?
不完全是。AJAX请求只是一个异步请求,响应类型应该取决于Content-type和Accept-type标头。AJAX请求请求实际上可以请求任何可能的内容类型——JSON是最常用的,也可以说是最有用的类型。
如果请求不包含特定的内容类型或接受类型,Rails将默认为html,除非您在路由中覆盖它:
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :things
end
end
Rails-UJS内置于Rails中,并为表单和链接上的remote: true
选项提供动力,它实际上使用application/javascript
作为默认内容类型,因为它允许您在不编写ajax处理程序的情况下编写js.erb
视图和重用Rails模板。如果这真的是一个好主意,尽管这会导致一些非常有问题的设计决策,这是有争议的。
使用Rails-UJS,设置内容类型的最简单方法是通过data-type
属性:
<%= link_to "Click Me!", "/foo", remote: true, data: { type: :json } %>
<%= form_with(model, html: { data: { type: "json" }}) %>
如果使用XMLHttpRequest"手动"发送Ajax请求,则可以使用setRequestHeader
设置内容类型。
xhr.setRequestHeader("Content-Type", "application/json");
使用jQuery,您可以为ajax函数或jQuery.getJSON
使用type:
选项。
此外,正确的响应方式是使用201 Created来响应成功的POST请求。
201已创建。请求已得到满足,并导致一个或正在创建更多的新资源。由创建的主资源请求由响应,或者,如果未接收到位置字段,则由有效请求URI。
format.json { head :created, location: @role }
您还可以选择将创建的资源包含在响应主体中。
format.json { render json: @role, location: @role, status: :created }
form_with
默认情况下发送XHR (ajax)
请求,要求您为响应提供java-script template
,然后在response方法中使用format.js
。
但是,如果您想生成json
或任何其他请求格式(如xml
(,您可以将该格式作为参数传递给路径助手方法,如下所示:
admin_roles_path(format: :json)
或者直接在form_with
调用中使用format选项,但由于您已经在使用url
选项,format
选项将被省略。
想了解更多信息,这是一篇很好的文章。