Les rails détectent si la demande était AJAX

128

Dans mon action, je souhaite uniquement répondre avec un traitement s'il a été appelé à partir d'une requête AJAX. Comment vérifier?

Je veux faire quelque chose comme ça:

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
Razor Storm
la source

Réponses:

249

Vous pouvez vérifier header[X-Requested-With]si un pour voir s'il s'agit d'une requête AJAX. Voici un bon article sur la façon de le faire.

Voici un exemple:

if request.xhr?
  # respond to Ajax request
else
  # respond to normal request
end
Amir Raminfar
la source
Attention: cela ne fonctionne pas sur les remote: trueappels standard dans les nouvelles versions de Rails, car les en-têtes nécessaires ne sont pas définis.
Roland Studer
14

Si vous utilisez :remote => truedans vos liens ou formulaires, vous feriez:

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

Vous pouvez également vérifier avant le bloc respond_to en appelant request.xhr?.

Sean Hill
la source
26
Une requête ajax ne doit pas nécessairement répondre avec javascript, $.ajax({dataType: 'html'})c'est ajax qui répond avec HTML. La bonne façon de faire est la deuxième que vous avez mentionnéerequest.xhr?
Pablo Fernandez heelhook
3

Les documents disent que request.xhr?

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

Mais attention

request.xhr? 

renvoie des valeurs numériques ou nulles et non des valeurs BOOLEAN comme le disent les documents, conformément à = ~.

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

C'est basé sur ceci:

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

alors

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

Les docs:

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

pixelearth
la source
quelle est la différence entre truythy et boolean? les deux ne sont pas vrai / faux?
Arnold Roa
Vraiment signifiant que lorsqu'ils sont utilisés dans un contexte "booléen", vous devez les traiter non pas comme des booléens, mais comme des booléens qui seront convertis en booléens. Au-dessus de env ['HTTP_X_REQUESTED_WITH'] = ~ / XMLHttpRequest / renvoie 0 pas faux. Et 0 est en fait vrai, pas faux en rubis: 0 || 1 => 0 Mais je vais modifier mon message pour plus de clarté.
pixelearth
Mais il est normal d'être honnête, le zéro signifie que le texte est trouvé à l'index 0, donc il est trouvé (et sa requête et ajax). Si le texte n'est pas trouvé, le résultat nilest faux.
Arnold Roa
2
Oui, mais la convention est généralement pour method_name? pour retourner BOOL, donc c'est un gotcha
pixelearth
0

J'aime utiliser des before_actionfiltres. Ils sont particulièrement utiles lorsque vous avez besoin du même filtre / autorisation pour plusieurs 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
HarlemÉcureuil
la source
0
request.xhr? 

si ce retourne 0 alors cela signifie que c'est une requête ajax, sinon il retournera nil

vidur punj
la source