Проверка HTTP-запроса на аяксовость (ajax) 4
При написании приложения по принципам MVC с использованием Ajax, часто для одного и того же запроса нужно получить данные в двух отличных друг от друга вариантах—в чистом HTML и в XML/json для Ajax запроса. А т.к. один и тот же контроллер в MVC обрабатывает оба типа запроса и скорее всего было бы удобно для его обработки использовать один и тот же URL, надо как-то отличать их, чтоб знать в каком формате отдать данные. Если это POST-запрос то можно просто создать дополнительное поле/переменную в запросе, а если GET, то нужно или отдельный URL для каждого типа данных или дополнительный заголовок в запросе (см. ниже почему).
Проблема мне кажется больше именно в GET запросе. Если следовать правилам ReST, то контент полученный по URL должен быть кеширован, а в нашем случае будет кеширован первый формат, в котором контроллер отдаст контент. Было бы удобно чтоб контроллер делал проверку на наличие каких-то заголовков и отдавал в зависимости от них ответ в нужном виде, но вот кеширование этому помешает. Т.к. кеш скеширует контент на первый попавшийся запрос (Ajax/HTML) и для следующего отличного запроса может быть отдан контент в неверном формате. Конечно можно с помощью заголовков вообще отключить кеширование, но это неоправдано, т.к. в протоколе HTTP не зря предусмтрена такая функциональность.
В общем решением была бы возможность реагирования кеша на определенные заголовки от сервера. И да, это указано в стандарте HTTP и реализовано как клиентами так и серверами. Есть такой заголовок в стандарте HTTP—Vary:, обычно его называют Vary Header. Он необходим как раз для осуществления правильного кеширование в зависимости от его значения. По большому счету он нужен чтоб указать кешу для какого заголовка запроса скеширован данный URL. Т.е. контент в кеше теперь будет идентифицироваться не только по URL, но по URL + заголовок указанный директивой Vary. Например, если пользователь залогинен на сайт с использованием Cookie, тогда заголовок Vary должен выглядеть так Vary: Cookie. URL в это случае, например, будет /profile/ (профиль пользователя) и два разных пользователя, попав на страницу из одного кеша будут проверены с помощью директивы Vary на предмет Cookie и получат разный контент. Или например кеширование должно производиться с учетом языка пользователя, тогда директива будет выглядить так Vary: Content-Language.
Зачем это нужно в нашем случае? Все просто—практически все Javascript Toolkits используют заголовок HTTP_X_REQUESTED_WITH со значением ‘XMLHttpRequest’. Так что если мы поставим Vary: HTTP_X_REQUESTED_WITH, то оба запроса к одному URL но от разных инициаторов (сам браузер или javascript/ajax код) будут скешированы отдельно.
Вот такой интересный нюанс. Может кому-то пригодится в деле.
Trackbacks
Use the following link to trackback from your own site:
http://livedev.org/trackbacks?article_id=http-ajax-query-check&day=25&month=04&year=2007







Я бы еще предложил использовать не свой заголовок "ajax/не ajax", а заголовок Accept, в котором обычные запросы идут с предпочтением Content-Type: text/html, а на ajax'овых запросах туда можно вписывать что нужно: application/javascript, application/xml. Поскольку в итоге нам нужно кешировать именно разные типы контента, это то, что нужно.
Хорошая идея. Только есть небольшой стрем, если в браузере каким-то макаром будет стоять принятие, например application/xml первым по умолчанию (может плагин какой это включить может), то это может помешать скрипту на серверной стороне. Идеальным было бы использование тогда Content-type, какого кроме как в ajax использовать нереально :-) Например, application/json, волне кандидат.
Привет)) Меня тоже зовут Илья. И я тоже веб-дизайнер))). Хорошая статья спасибо!
фигня полная, решает ряд проблем в узком кругу, как с PHP+IIS прикажите быть?)