Railsy wykrywają, czy żądanie było AJAX

128

W mojej akcji chcę odpowiedzieć przetwarzaniem tylko wtedy, gdy zostało wywołane z żądania AJAX. Jak to sprawdzić?

Chcę zrobić coś takiego:

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
źródło

Odpowiedzi:

249

Możesz sprawdzić, header[X-Requested-With]czy jest to żądanie AJAX. Oto dobry artykuł o tym, jak to zrobić.

Oto przykład:

if request.xhr?
  # respond to Ajax request
else
  # respond to normal request
end
Amir Raminfar
źródło
Ostrzeżenie: to nie działa w przypadku standardowych remote: truewywołań w nowszych wersjach Railsów, ponieważ niezbędne nagłówki nie są ustawiane.
Roland Studer
14

Jeśli używasz :remote => truew swoich linkach lub formularzach, zrobiłbyś:

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

Możesz również sprawdzić przed blokiem respond_to dzwoniąc request.xhr?.

Sean Hill
źródło
26
Żądanie Ajax niekoniecznie musi odpowiadać javascriptem, $.ajax({dataType: 'html'})to Ajax, który odpowiada za pomocą HTML. Właściwy sposób, aby to zrobić, to drugi, o którym wspomniałeśrequest.xhr?
Pablo Fernandez heelhook
3

Doktorzy mówią, że request.xhr?

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

Ale UWAŻAJ na to

request.xhr? 

zwraca wartości numeryczne lub zerowe, a nie wartości typu BOOLEAN, jak mówią dokumentacja, zgodnie z = ~.

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

Opiera się na tym:

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

więc

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

Dokumenty:

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

pixelearth
źródło
jaka jest różnica między truythy a boolean? oba nie są prawdziwe / fałszywe?
Arnold Roa
Prawda oznacza, że ​​gdy jest używany w kontekście „boolowskim”, należy traktować je nie jako wartości logiczne, ale takie, które zostaną przypisane do wartości boolowskich. Powyżej env ['HTTP_X_REQUESTED_WITH'] = ~ / XMLHttpRequest / zwraca 0 nie fałsz. A 0 jest faktycznie prawdą, a nie fałszem w rubinowym: 0 || 1 => 0 Ale mam zamiar zmienić mój post dla jasności.
pixelearth
Ale prawda jest taka, że ​​zero oznacza, że ​​tekst znajduje się pod indeksem 0, więc został znaleziony (oraz jego żądanie i żądanie AJAX). Jeśli tekst nie zostanie znaleziony, wynikiem niljest fałsz.
Arnold Roa
2
Tak, ale konwencja dotyczy ogólnie nazwa_metody? aby zwrócić BOOL, więc to jest
problem
0

Lubię używać before_actionfiltrów. Są szczególnie przydatne, gdy potrzebujesz tego samego filtru / autoryzacji do wielu działań.

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
HarlemSquirrel
źródło
0
request.xhr? 

jeśli to zwróci 0, oznacza to, że jest to żądanie AJAX, w przeciwnym razie zwróci nil

vidur punj
źródło