понедельник, 12 сентября 2011 г.

Передача клиенту дополнительной информации при REST запросах

Подобного не встречал, но думаю что я не первый кто до этого додумался. Что бы не передавать в теле ответа мета информацию, её можно передавать в HTTP-заголовке. Произвольные поля в заголовок можно передавать с префиксом "X-". Хочу показать как подобное реализовать на рельсах и как удобно получать эти заголовки на JS-клиенте. Ну за одно покажу как избежать одного нюанса. Я покажу на примере передачи flash сообщений при JSON-запросов.

Для начала добавим в ApplicationController метод добавления flash сообщений в заголовок. Для flash[:alert] это будет X-ALERT, для всех остальных аналогично. В заголовку юникод понимает  только хром, по этому сообщения нужно кодировать. Кодировать мы будем в url-encode, потому что на JS-клиете так раскодировать проще.

def json_flash
  return unless [ :json ].include? request.format.to_sym
  flash.each do |name, message| 
    response.headers['X-' + name.to_s] = URI.encode(message)
  end
  flash.clear
end

Вызывать этот метод будем через alfter_filter:

after_filter :json_flash

Поскольку после срабатывания rescue_from не вызываются фильтры, то нужно будет вручную вызывать json_flash.

С серверной частью всё. На JS-клиенте биндим калбек  для json-запросов, причём на событие completed, а не success и error:

$('body').ajaxComplete(function(data, xhr){
  _(['alert', 'notice']).each(function(field){
    var notice = xhr.getResponseHeader('X-' + field);
    if(notice){
      notice = decodeURI(notice);
      alert(notice);
    }
  });
});

"_" - это функция из underscope,js.

Вот и всё.

Комментариев нет:

Отправить комментарий