Rails определяет, был ли запрос AJAX


128

В своем действии я хочу ответить обработкой только в том случае, если она была вызвана из запроса 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

Ответы:


249

Вы можете проверить, является header[X-Requested-With]ли это запросом AJAX. Вот хорошая статья о том, как это сделать.

Вот пример:

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

Предупреждение: это не работает со стандартными remote: trueвызовами в новых версиях Rails, так как необходимые заголовки не устанавливаются.
Роланд Студер

14

Если вы используете :remote => trueв своих ссылках или формах, вы должны:

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

Вы также можете проверить перед блоком response_to, позвонив request.xhr?.


26
Запрос ajax не обязательно должен отвечать с помощью javascript, $.ajax({dataType: 'html'})это ajax, который отвечает с помощью HTML. Правильный способ сделать это - второй из упомянутых вамиrequest.xhr?
Pablo Fernandez heelhook

3

Документы говорят, что request.xhr?

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

Но ОСТЕРЕГАЙТЕСЬ, что

request.xhr? 

возвращает числовые или нулевые значения, а не БУЛЕВЫЕ значения, как говорится в документации, в соответствии с = ~.

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, а не ложь. И 0 на самом деле истинно, а не ложно в рубине: 0 || 1 => 0 Но я собираюсь переделать свой пост для ясности.
pixelearth

Но все в порядке, чтобы быть правдой, ноль означает, что текст найден с индексом 0, поэтому он найден (и его запрос и запрос ajax). Если текст не найден, результат nilбудет ложным.
Арнольд Роа

2
Да, но обычно это соглашение для method_name? чтобы вернуть BOOL, так что это
ошибка

0

Мне нравится использовать 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

0
request.xhr? 

если это возвращает 0, это означает, что это запрос ajax, иначе он вернет ноль

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.