Rails detect if request was AJAX

Ruby on-RailsAjax

Ruby on-Rails Problem Overview


In my action I wish to only respond with processing if it was called from an AJAX request. How do I check?

I want to do something like this:

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 Solutions


Solution 1 - Ruby on-Rails

You can check for a header[X-Requested-With] to see if it is an AJAX request. Here is a good article on how to do it.

Here is an example:

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

Solution 2 - Ruby on-Rails

If you're using :remote => true in your links or forms, you'd do:

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

You can also check before the respond_to block by calling request.xhr?.

Solution 3 - Ruby on-Rails

Update:

As of Rails 6.1.0, xhr?() does actually (finally) return a boolean value.

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


Original Answer:

The docs say that request.xhr?

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

But BEWARE that

request.xhr? 

returns numeric or nil values not BOOLEAN values as the docs say, in accordance with =~.

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

It's based on this:

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

so

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

The docs:

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

Solution 4 - Ruby on-Rails

I like using before_action filters. They are especially nice when you need the same filter/authorization for multiple actions.

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

Solution 5 - Ruby on-Rails

request.xhr? 

if this return 0 then it means its an ajax request, else it will return nil

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRazor StormView Question on Stackoverflow
Solution 1 - Ruby on-RailsAmir RaminfarView Answer on Stackoverflow
Solution 2 - Ruby on-RailsSean HillView Answer on Stackoverflow
Solution 3 - Ruby on-RailspixelearthView Answer on Stackoverflow
Solution 4 - Ruby on-RailsHarlemSquirrelView Answer on Stackoverflow
Solution 5 - Ruby on-Railsvidur punjView Answer on Stackoverflow