【发布时间】:2011-11-26 12:29:46
【问题描述】:
我得到一个调用控制器方法 getInfo 的 GET URL。可以通过 mydomain.com/getInfo.json?params=BLAHBLAH 或 mydomain.com/getInfo?params=BLAHBLAH
调用在控制器中,有没有办法检测用户如何调用它?
【问题讨论】:
标签: ruby-on-rails
我得到一个调用控制器方法 getInfo 的 GET URL。可以通过 mydomain.com/getInfo.json?params=BLAHBLAH 或 mydomain.com/getInfo?params=BLAHBLAH
调用在控制器中,有没有办法检测用户如何调用它?
【问题讨论】:
标签: ruby-on-rails
是的。在控制器中,您可以调用request.format 方法来确定用户请求的格式。
如果您需要的不仅仅是格式,您可以查看request.url 以获取完整的 URL。有关request 对象的更多详细信息,请参见here。
【讨论】:
Mime::Type 进行== 比较,例如request.format == 'json'。还有一个方便的#html? 方法,例如before_action :do_something if: "request.format.html?"
在你的控制器的特定方法中,你可以响应不同的格式——例如:
respond_to do |format|
format.html
format.json { render :json => @user }
end
您可以响应各种格式(xml、js、json 等) - 您可以在此处获取有关 respond_to 以及如何在控制器中使用它的更多信息:
http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to
【讨论】:
这是一个实际的有点做作的工作示例,它回答了如何检测调用是 JSON/XML API 调用还是“HTML”调用的问题。 (Accepted answer不回答那个问题,只是告诉你如何应对各种格式)
# We can use this in a before_filter
skip_before_action :verify_authenticity_token, if: :api_request?
# Or in the action
def show
@user = if api_request?
User.where(api_token: params[:token]).first
else
User.find(params[:id])
end
respond_to do |format|
format.html
format.json { render :json => @user }
end
end
private
def api_request?
request.format.json? || request.format.xml?
end
使用respond_to 设置不同类型的响应,但它不会告诉您的应用程序是如何进行调用的,除非您添加一些额外的代码来执行此操作(请参见下面的粗略示例,只是为了说明这一点。 )
我不建议这样做,询问 request 更安全,并且有用 10 倍,因为下面的方法仅在请求生命周期的后期(在将响应发送回客户端之前)有用。如果您在之前的过滤器中有任何逻辑,这根本不起作用。
# Have no way of using it in a before_filter
# In your controller
def show
# I want to know if the call was JSON API - right here
# This approach wouldn't help at all.
@user = User.find(params[:id])
respond_to do |format|
format.html { @api_request = false}
format.json { @api_request = true; render :json => @user }
end
end
def api_request?
@api_request
end
【讨论】:
检查 json 的方法列表
request.format == 'json'
request.format == :json
request.format.json?
request.path.match('json')
request.url.match('json')
respond_to do |format|
format.json { render json: [] }
end
您还可以检查请求是否为 ajax 请求
request.xhr?
【讨论】:
就这么简单:
request.path_parameters[:format] == 'json'
【讨论】:
如果您需要检查它是否是 Ajax 请求,您可以使用 request.xhr? 来检查 header[X-Requested-With]
示例代码sn-p
if request.xhr?
# Do the ajax stuff
else
# Do normal stuff
end
【讨论】: