Os trilhos detectam se a solicitação foi AJAX

128

Na minha ação, desejo responder apenas com o processamento se for chamado de uma solicitação AJAX. Como faço para verificar?

Eu quero fazer algo assim:

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
Tempestade de Navalha
fonte

Respostas:

249

Você pode verificar a header[X-Requested-With]para ver se é uma solicitação AJAX. Aqui está um bom artigo sobre como fazê-lo.

Aqui está um exemplo:

if request.xhr?
  # respond to Ajax request
else
  # respond to normal request
end
Amir Raminfar
fonte
Aviso: isso não funciona em remote: truechamadas padrão nas versões mais recentes do Rails, pois os cabeçalhos necessários não são definidos.
Roland Studer
14

Se você estiver usando :remote => trueseus links ou formulários, faça:

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

Você também pode verificar antes do bloco respond_to ligando request.xhr?.

Sean Hill
fonte
26
Uma solicitação ajax não precisa necessariamente responder com javascript, $.ajax({dataType: 'html'})é ajax que responde com HTML. O caminho certo para fazer isso, é o segundo que você mencionourequest.xhr?
Pablo Fernandez heelhook
3

Os documentos dizem que request.xhr?

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

Mas cuidado que

request.xhr? 

retorna valores numéricos ou nulos, não valores BOOLEAN, como dizem os documentos, de acordo com = ~.

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

É baseado nisso:

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

tão

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

Os documentos:

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

pixelearth
fonte
qual é a diferença entre truythy e boolean? ambos não são verdadeiros / falsos?
Arnold Roa
Verdadeiramente, significa que, quando usado em um contexto "booleano", você deve tratá-los não como não booleanos, mas como aqueles que serão convertidos em booleanos. Acima env ['HTTP_X_REQUESTED_WITH'] = ~ / XMLHttpRequest / retorna 0 não falso. E 0 é realmente verdade, não falsey em ruby: 0 || 1 => 0 Mas vou alterar minha postagem para maior clareza.
pixelearth
Mas, se é verdade, o zero significa que o texto é encontrado no índice 0; portanto, é encontrado (e sua solicitação e ajax). Se o texto não for encontrado, o resultado nilserá falso.
Arnold Roa
2
Sim, mas a convenção geralmente é para method_name? retornar BOOL, então esta é uma pegadinha
pixelearth
0

Eu gosto de usar before_actionfiltros. Eles são especialmente agradáveis ​​quando você precisa do mesmo filtro / autorização para várias ações.

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
fonte
0
request.xhr? 

se esse retorno 0, significa que é uma solicitação ajax; caso contrário, ele retornará nulo

vidur punj
fonte