2015-10-08 4 views
2

Когда я отправляю запрос ajax моему рубиновому контроллеру, функция before_filter вызывается дважды для каждого запроса ajax. Я использую before_filter для аутентификации.Ruby On Rails before_filter называется дважды?

Аякса запрос я использую:

$.ajax({ 
    type: 'GET', 
    url: 'URL_TO__RoR_Controller', 
    username: username, 
    password: password, 
    contentType: "application/json; charset=utf-8", 
    success: function(data){ 
     console.log(data); 
    }, 
    error: function(xhr, ajaxOptions, thrownError) { 
     console.log(arguments); 
    } 
    }); 

Код RoR:

class Api::MyController < ApplicationController 
before_filter :authenticate 
attr_reader :current_user 

def authenticate 
print "===================================\n" 
authenticate_or_request_with_http_basic do |username, password| 
    print "\n--------------------------------\n" 
    print username, password 
    print "\n--------------------------------\n" 
    @current_user = User.authenticate(username, password) 
    print "===================================\n" 
end 
end 

def show 
print "=================IN SHOW==================" 
end 
end 

Ответ RoR на запрос Ajax:

Started GET "URL_TO__RoR_Controller" for 127.0.0.1 at 2015-10-08 10:18:18 +0200 
Processing by Api::MyController#show as JSON 
    Parameters: {"id"=>"show", "test"=>{}} 
=================================== 
=================================== 
Filter chain halted as :authenticate rendered or redirected 
Completed 401 Unauthorized in 1ms (ActiveRecord: 1.0ms) 


Started GET "URL_TO__RoR_Controller" for 127.0.0.1 at 2015-10-08 10:18:19 +0200 
Processing by Api::MyController#show as JSON 
    Parameters: {"id"=>"show", "test"=>{}} 
=================================== 

-------------------------------- 
USERPASS 
-------------------------------- 
    User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`authorized` = 1 AND `users`.`login` = 'USER' LIMIT 1 
=================================== 
=================IN SHOW================== 
    Rendered URL_TO__RoR_Controller/show.json.rabl (0.8ms) 
Completed 200 OK in 30ms (Views: 3.4ms | ActiveRecord: 1.7ms) 

RoR конфигурации/routes.rb для этого одного контроллера:

Api::Application.routes.draw do 
namespace :api, defaults: { format: :json } do 
     resources :MyController, only: [:show] 
    end 
end 

Так в основном функция Аутентифицировать, кажется, выполняется дважды для каждого запроса Ajax шлю. Похоже, что первая попытка аутентификации завершилась неудачей. Он даже не попадает в функцию authenticate_or_request_with_http_basic. Во второй раз все кажется прекрасным.

Очевидно, что это неправильное поведение. Что вызывает эту проблему?

Edit:

Хорошо вот мои выводы при удалении before_filter:

1) При вынимании before_filter полностью проблема не возникает больше.

2) При сохранении/использовании before_filter, но заменяя authenticate_or_request_with_http_basic с 'истинным', как это:

def authenticate 
true 
end 

проблема не происходит либо. Таким образом, проблема, похоже, вызвана authenticate_or_request_with_http_basic?

+0

Возможно, это связано с процедурой ** CORS **. Сначала jQuery отправляет запрос перед полетом, а затем реальный. Можете ли вы предоставить свою конфигурацию 'config/routes.rb' и историю запросов вашего браузера? – Aetherus

+0

Я не уверен, что вы имеете в виду с историей запросов браузера. Я добавил confige/routes.rb в исходное сообщение. Я также попытался отправить запрос с помощью приложений Windows и с помощью python Request. Эта проблема возникла с приложениями Windows, но не возникла с запросом python. Я не знаю, как запрос отправляется с приложениями Windows, потому что у меня нет доступа к исходному коду. – MeesterPatat

+1

Типичный вариант использования для отладчика. установить точку останова в методе проверки подлинности. – Meier

ответ

0

Это не произойдет, если оно не вызвано каким-то образом.

И, видя, что запросы направляются в 1 секунду между собой, это говорит о том, что ваш Ajax посылается дважды:

127.0.0.1 at 2015-10-08 10:18:18 +0200 
127.0.0.1 at 2015-10-08 10:18:19 +0200 

Хотя это не ответ сам по себе, есть ряд вещей, которые вы можете сделать, чтобы «отладки» это:

  1. Во-первых, вы должны понимать, что это не будет происходить сама по себе
  2. Процесс «отладки» это просто случай определения того, что происходит & разрешения его
  3. Я не думаю, что Rails будет срабатывать действие контроллера дважды без его вызова

Таким образом, , вы должны смотреть на различные элементы задачи:


Во-первых, ваш Ajax запрос, похоже, срабатывает дважды.

Вы ввели следующий код:

$.ajax({ 
    type: 'GET', 
    url: 'URL_TO__RoR_Controller', 
    username: username, 
    password: password, 
    contentType: "application/json; charset=utf-8", 
    success: function(data){ 
     console.log(data); 
    }, 
    error: function(xhr, ajaxOptions, thrownError) { 
     console.log(arguments); 
    } 
}); 

Это делает не показать нам, как это связано с элементами на вашей странице. Я бы предположил, что у вас проблемы с Turbolinks.

Первый шаг для отладки заключается в том, чтобы не препятствовать привязке к JS. В частности, вы хотите, чтобы убедиться, что вы в своих интересах turbolinks hooks (page:load):

#app/assets/javascripts/application.js 
bind = function() { 
    $(".element").on("click", function() { 
     // Ajax 
    }); 
}; 
$(document).on("ready page:load", bind); 

Или вы могли бы делегировать из документа:

#app/assets/javascripts/application.js 
$(document).on("click", ".element", function() { 
    // Ajax 
}); 

Во-вторых, появляются ваши действия контроллера для вызова дважды, но это не только before_filter ... это весь поток (во втором случае).

Filter chain halted as :authenticate rendered or redirected 
Completed 401 Unauthorized in 1ms (ActiveRecord: 1.0ms) 

Единственная причина, по которой первый before_filter не огонь, потому что вы не были проверены. Я не знаю, как вы аутентифицируете пользователей, но если бы вы смогли это сделать, я бы подумал, что поток случится.

Итак, вопрос тогда станет как вы получаете первый запрос отскок?

Если вы делаете что-либо по-другому между двумя запросами, нам нужно это увидеть.Не то, что я думаю, что вы знаете, что он делает это автоматически :)

-

Это может быть подкреплено наблюдением "network" requests sent to the server с Аяксом:

enter image description here


Наконец, вы хотите сделать некоторые тесты без метода before_filter, чтобы узнать, будет ли это работать. Возможно, у вас нет правильных токенов аутентификации или другой проблемы в промежуточном программном обеспечении.

+0

На самом деле запросы отправляются одновременно. Я попытался воспроизвести два запроса, отправленных в разное время, и я потерпел неудачу. Причина разницы во времени ответа RoR в моем первом сообщении (вопрос), вероятно, является ошибкой копирования-вставки. Я использовал метод «делегат из документа», но это не имело никакого значения. Снимок экрана из сетевого окна после отправки запроса один раз: http://i.imgur.com/JPc6pUF.png. Я собираюсь сделать некоторые тесты без before_filter и написать свое открытие здесь. – MeesterPatat

+0

См. EDIT в моем первоначальном вопросе о моих выводах при удалении файла before_filter. – MeesterPatat

Смежные вопросы