Rails не перезагружает сессию на пост ajax - PullRequest
61 голосов
/ 26 февраля 2011

У меня очень странная проблема с Rails и ajax при использовании jQuery (хотя я не думаю, что это специфично для jQuery).

Мое приложение Rails использует хранилище сеансов cookie, и у меня очень простой логин, который устанавливает идентификатор пользователя в сеансе. Если user_id не установлен в сеансе, он перенаправляется на страницу входа. Это работает без проблем. Запросы JQuery GET тоже работают нормально. Проблема в том, что когда я делаю JQuery POST - браузер отправляет cookie сессии нормально (я подтвердил это с помощью Firebug и выгрузил request.cookies в журнал), но сессия пуста, то есть сессия {}.

Я делаю это в моем application.js:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

и вот мой пример сообщения:

$.post('/test/1', { _method: 'delete' }, null, 'json');

который должен получить этот метод контроллера (_method: delete):

def destroy
  respond_to do |format|
    format.json { render :json => { :destroyed => 'ok' }.to_json }
  end
end

Глядя на журнал и используя Firebug, я могу подтвердить, что при отправке сообщения ajax в заголовке запроса отправляется правильное значение cookie, но кажется, что в какой-то момент Rails теряет это значение и, следовательно, теряет сеанс, поэтому он перенаправляет на страницу входа и никогда не попадает в метод.

Я перепробовал все, что мог придумать, чтобы отладить это, но я пришел к мысли, что это может быть ошибкой в ​​Rails. Я использую Rails 3.0.4 и jQuery 1.5, если это поможет. Я нахожу очень странным, что обычные (т.е. не-ajax) запросы на получение и публикацию работают, и запросы на получение ajax работают без проблем, просто сообщения ajax не работают.

Любая помощь в попытке исправить это будет принята с благодарностью!

Большое спасибо,
Dave

Ответы [ 3 ]

113 голосов
/ 26 февраля 2011

Я собираюсь ответить на свой вопрос, так как мне удалось понять, что происходит.Я опубликую это здесь на случай, если это пригодится кому-либо еще!

После дальнейшего изучения я выяснил, что код, который был , предполагал для установки заголовка запроса с токеном CSRF,не было.Это был оригинальный код:

$(document).ajaxSend(function(e, xhr, options) {
  var token = $("meta[name='csrf-token']").attr('content');
  xhr.setRequestHeader('X-CSRF-Token', token);
});

То, что происходило, было то, что этот код не устанавливал заголовок, Rails получал запрос Ajax, токен не совпадал, и он сбрасывал сеанс.Раньше это вызывало ошибку ActionController :: InvalidAuthenticityToken (я полагаю, я бы поймал это раньше, если бы возникла ошибка ... да ладно), но начиная с Rails 3.0.4, теперь он просто тихо сбрасывает сессию.

Таким образом, чтобы отправить токен в шапке, вы должны сделать это (большое спасибо этому замечательному сообщению в блоге ):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
}); 

И теперь все работает так, как должно.Что приятно.

5 голосов
/ 17 июня 2011

Я нашел другой случай:

Вы установили 'csrf_meta_tag' в файле макета приложения?

в моем случае я не установил этот тег и столкнулся с той же проблемой, что и ваш.

И после установки csrf_meta_tag в app / views / layouts / application.html.erb все работает отлично!

Наконец, спасибо, что помогли мне найти причину! Большое спасибо ~

0 голосов
/ 07 июня 2011

Для этого и предназначен официальный адаптер рельсов jquery-ujs в серии 3.0.Вы должны помнить, что нужно обновлять его при обновлении версий rails.

Для меня обновление с 3.0.3 до 3.0.8.rc4 означало также ручное извлечение файла src/rails.js из связанного репо.

Поскольку Rails 3.1 наконец-то переключился на jQuery, в будущем все должно автоматически обновляться через гем jquery-rails при обновлении rails (и с использованием встроенного в 3.1 конвейера ресурсов)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...