【问题标题】:Rails detect if request was AJAXRails 检测请求是否为 AJAX
【发布时间】:2012-01-03 11:26:23
【问题描述】:

在我的操作中,我希望仅在从 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

【问题讨论】:

    标签: ruby-on-rails ajax


    【解决方案1】:

    您可以检查 header[X-Requested-With] 以查看它是否是 AJAX 请求。这是一个很好的article,关于如何做到这一点。

    这是一个例子:

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

    【讨论】:

    • 警告:这不适用于较新 Rails 版本中的标准 remote: true 调用,因为没有设置必要的标头。
    【解决方案2】:

    如果您在链接或表单中使用:remote => true,您会这样做:

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

    您也可以通过调用request.xhr? 在respond_to 块之前检查。

    【讨论】:

    • 一个ajax请求不一定要用javascript响应,$.ajax({dataType: 'html'})是用HTML响应的ajax。正确的做法,是你提到的第二种方法request.xhr?
    【解决方案3】:

    更新:

    从 Rails 6.1.0 开始,xhr?() 实际上(最终)返回一个布尔值。

    https://github.com/rails/rails/commit/0196551e6039ca864d1eee1e01819fcae12c1dc9#diff-60b77e427ea7ba142faa477fac10b8d0134cede4e35a3b1953c425200fadf1acL267-L269


    原答案:

    文档说 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

    【讨论】:

    • 真值和布尔值有什么区别?两者都不是真/假?
    • 真实的意思是,当在“布尔”上下文中使用时,您必须将它们视为不是布尔值,而是将其转换为布尔值。以上 env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/ 返回 0 而不是 false。而 0 实际上是真实的,而不是 ruby​​ 中的虚假:0 || 1 => 0 但为了清楚起见,我将更改我的帖子。
    • 但它是真实的,零表示文本在索引 0 处找到,因此它被找到(以及它和 ajax 请求)。如果未找到文本,则结果为nil,这是错误的。
    • 是的,但是约定一般是针对method_name的?返回 BOOL,所以这是一个陷阱
    【解决方案4】:

    我喜欢使用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
    

    【讨论】:

      【解决方案5】:
      request.xhr? 
      

      如果返回 0 则表示它是一个 ajax 请求,否则它将返回 nil

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 2012-06-02
        • 2021-06-25
        相关资源
        最近更新 更多