Rails检测请求是否为AJAX


128

在我的动作中,我只希望响应从AJAX请求中调用的处理。我该如何检查?

我想做这样的事情:

def action
   @model = Model.find(params[:id])

   respond_to do |format|

      if (wasAJAXRequest()) #How do I do this?

         format.html #action.html.erb

      else

         format.html {redirect_to root_url}
   end
end

Answers:


249

您可以检查是否为header[X-Requested-With]AJAX请求。这是一篇很好的文章

这是一个例子:

if request.xhr?
  # respond to Ajax request
else
  # respond to normal request
end

警告:remote: true在较新的Rails版本中,这不适用于标准调用,因为未设置必要的标头。
罗兰·史都德

14

如果要:remote => true在链接或表单中使用,请执行以下操作:

respond_to do |format|
  format.js { #Do some stuff }

您还可以通过调用来在response_to块之前进行检查request.xhr?


26
一个ajax请求不一定必须使用JavaScript响应,$.ajax({dataType: 'html'})而是一个使用HTML响应的ajax。正确的方法是您提到的第二个方法request.xhr?
Pablo Fernandez脚跟钩2012年

3

文档说那个request.xhr?

Returns true if the X-Requested-With header contains XMLHttpRequest”....

但是要注意

request.xhr? 

按照=〜返回数值或nil值,而不是文档所说的BOOLEAN值。

irb(main):004:0> /hay/ =~ 'haystack'
=> 0
irb(main):006:0> /stack/ =~ 'haystack'
=> 3
irb(main):005:0> /asfd/ =~ 'haystack'
=> nil

基于此:

# File actionpack/lib/action_dispatch/http/request.rb, line 220
def xml_http_request?
  @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/
end

所以

env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/  => 0

该文档:

http://apidock.com/rails/v4.2.1/ActionDispatch/Request/xml_http_request%3F


truythy和boolean有什么区别?两者都不是真/假?
阿诺德·罗阿

真实的含义是,在“布尔”上下文中使用时,您不必将它们视为不是布尔,而是将被转换为布尔值的布尔。在env ['HTTP_X_REQUESTED_WITH'] =〜/ XMLHttpRequest /之上,返回0而不是false。0实际上是真实的,而不是红宝石中的虚假:0 || 1 => 0但是为了清楚起见,我将更改帖子。
pixelearth '17

但是它确实是真实的,零表示在索引0处找到了文本,因此找到了它(及其和Ajax请求)。如果找不到文本,则结果为nil,这是错误的。
阿诺德·罗阿

2
是的,但是约定通常是针对method_name的?返回布尔,所以这是一个
陷阱

0

我喜欢使用before_action过滤器。当您需要多个操作具有相同的过滤器/授权时,它们特别好。

class MyController < AuthController
  before_action :require_xhr_request, only: [:action, :action_2]

  def action
    @model = Model.find(params[:id])
  end

  def action_2
    # load resource(s)
  end

  private

  def require_xhr_request
    redirect_to(root_url) unless request.xhr?
  end
end

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.