LINUX.ORG.RU

Чем плохи GET запросы с параметрами?


0

1

А в народе попросту GET запросы.

Вот говорят, URLы должны быть читаемыми. А зачем? И разве GET запрос менее читаемый?

Вот к примеру есть http://site/car/2000/right/left чем это белее понятно чем http://site/?section=car&capacity=2000&wheel=right&cargo=left ?

Ну ты мозги-то включи. Очевидно же.

Zhbert ★★★★★ ()

Для удобства же. Там где удобно, надо применять HRU. А тем, где неудобно, соответственно, не применять.

geekless ★★ ()

Вот к примеру есть http://site/car/2000/right/left чем это белее понятно чем http://site/?section=car&capacity=2000&wheel=right&cargo=left ?

Данный пример не показательный. Что первый что второй вариант малопонятны. А если сравнить

http://tourist.kharkov.ua/phpbb/viewtopic.php?f=25&p=695877 и http://tourist.kharkov.ua/phpbb/Велофорум-общий/Велотрусы-и-температура/ то по внешнему виду ссылки понятно, что там следует ожидать

А если и с этим примером не понятно, то это может означать, что вы стали мыслить не как человек, как php :)

azure ★★ ()
Ответ на: комментарий от Zhbert

А в конечном счете это приводит и к повышению в поисковике.

azure ★★ ()

Кронос же разъяснил уже по хардкору, зачем.

//Сижу, курю megasplat в Dancer

Hoodoo ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Скажем прямо, если поисковик не умеет расчехлять GET запросы в урлах - он никому не нужен.

azure ★★ ()
Ответ на: комментарий от azure

http://tourist.kharkov.ua/phpbb/Велофорум-общий/Велотрусы-и-температура/

Этому URL следует выглядеть как http://tourist.kharkov.ua/phpbb/123456/Велофорум-общий/Велотрусы-и-температура/ чтобы быть устойчивым к переименованию треда или переносу в другой раздел.

geekless ★★ ()

1. ЧПУ. Более короткая ссылка нагляднее. И твой пример это ярко показывает.

2. Кеширование. GET обычно не кешируются браузером и не могут кешироваться статически сервером.

3. Однозначность ссылок (параметры GET-запроса поменяй местами и получишь другую ссылку (как строку) на ту же страницу) — весьма актуально для всяких рефереров и поисковиков.

4. Из-за неоднозначности (п.3) сложнее (порой, совсем невозможно) реализовать рерайты/редиректы при последующих переделках структуры сайта.

5. ... В общем, достаточно уже и перечисленного, чтобы GET-ссылки шли лесом не оглядываясь :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от geekless

Это вы откуда такое взяли?

Какое конкретно из двух утверждений?

1 — из практики работы с браузерами
2 — из логики работы веб-серверов

KRoN73 ★★★★★ ()
Ответ на: комментарий от azure

Не пример. Тут да - понятнее. Но только засчет того, что сами параметры GET крайне непонятны. Я ведь могу сравнить и так:

http://tourist.kharkov.ua/phpbb/viewtopic.php?forum=Велофорум-общий&topic... и http://tourist.kharkov.ua/phpbb/25/695877/

И что теперь понятнее?

Suntechnic ★★★★★ ()
Ответ на: комментарий от KRoN73

из практики

Unless the origin server explicitly prohibits the caching of their responses, the application of GET and HEAD methods to any resources SHOULD NOT have side effects that would lead to erroneous behavior if these responses are taken from a cache. They MAY still have side effects, but a cache is not required to consider such side effects in its caching decisions. Caches are always expected to observe an origin server's explicit restrictions on caching.

We note one exception to this rule: since some applications have traditionally used GETs and HEADs with query URLs (those containing a "?" in the rel_path part) to perform operations with significant side effects, caches MUST NOT treat responses to such URIs as fresh unless the server provides an explicit expiration time.

geekless ★★ ()
Ответ на: комментарий от Suntechnic

И что теперь понятнее?

Первое даже ЛОР-движком обрезалось :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

Если в URI есть '?', и в ответе не указан expiration time, ответ не кэшируется.

Вывод: надо указывать expiration time, и всё будет хорошо.

geekless ★★ ()

Зависит от назначения параметра. Я бы переписал URL как http://site/car?capacity=2000&wheel=right&cargo=left. Просто потому что car - скорее часть пути, чем переменная. А бывает так, что все переменные - это часть пути и ведут к статичному документу. Так зачем, в таком случае, городить огород из параметров? Хороший пример тому - ссылки на новости и другие публикации. Но это не отменяет назначение параметров.

Вывод один - не нужно впадать в крайности.

d9d9 ★★★ ()
Ответ на: комментарий от geekless

Вывод: надо указывать expiration time, и всё будет хорошо.

Только у тех браузеров (и прокси), которые такое поддерживают.

А у них это не то, что от типа браузера, но даже от версии, порой, зависит :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

2. Кеширование. GET обычно не кешируются браузером и не могут кешироваться статически сервером.

при умелом подходе все работает. У меня даже sendfile висит на GET запросах для отдачи картинок.

xpahos ★★★★★ ()
Ответ на: комментарий от KRoN73

ЧПУ. Более короткая ссылка нагляднее. И твой пример это ярко показывает.

Да, но я уже очень давно не заглядывал в адресную строку своего браузера... И да - в G+ ты уже говорил это.

Кеширование. GET обычно не кешируются браузером и не могут кешироваться статически сервером.

«обычно» или не кешируются браузером? А сервером зачем кэшировать если ответ на такой запрос в любом случае динамически формируется? Если его надо закэшировать, то не приложение ли должно это сделать?

Однозначность ссылок (параметры GET-запроса поменяй местами и получишь другую ссылку (как строку) на ту же страницу) — весьма актуально для всяких рефереров и поисковиков.

О - признаю - аргумент. Об этом не думал.

Из-за неоднозначности (п.3) сложнее (порой, совсем невозможно) реализовать рерайты/редиректы при последующих переделках структуры сайта.

Ну если есть такая проблема, то это трабла приложения.

Вобщем пока только согласен с 3.

Suntechnic ★★★★★ ()
Ответ на: комментарий от Suntechnic

Если так, то в плане читаемости чиеловеком вариант с гет параметрами выигрывает. Но KRoN73 верно говорит про другие аспекты.

azure ★★ ()
Ответ на: комментарий от Suntechnic

«обычно» или не кешируются браузером?

Это зависит от конкретного браузера и его версии.

А сервером зачем кэшировать

Например, чтобы он мог отдавать не 10..100 страниц в секунду, а 10000…100000.

Если его надо закэшировать, то не приложение ли должно это сделать?

Статическое кеширование фронтендом работает на порядки быстрее самых быстрых приложений.

Ну если есть такая проблема, то это трабла приложения.

ЧПУ легче позволяют поменять потом приложение, если что, в отличие от GET-ссылок. Хотя бы потому, что любая ЧПУ-ссылка при рерайте сервера может превратиться в любую GET-ссылку, но не наоборот.

KRoN73 ★★★★★ ()
Ответ на: комментарий от azure

Да, кое что я уже осознал... Меня сейчас мучит вопрос как сделать реврайт для gatling - там такой фишки нет, да и хотелось бы иметь реврайт на стороне приложения а не сервера...

Suntechnic ★★★★★ ()
Ответ на: комментарий от KRoN73

Вот, кстати, ради скорости я и предлагал внести изменения в движок ЛОРа: чтобы каждое сообщение представляло собой отдельную веб-страницу, а тема состояла из основного сообщения и динамически создающихся iframe'ов, в которые подгружаются новые сообщения.

Это значительно ускорило бы работу. А то у меня последнее время средняя скорость домашнего интернета сотни Б/с, страничка ЛОРа грузится чуть ли не по полчаса!

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Suntechnic

«обычно» или не кешируются браузером?

Все кешируется ровно настолько, насколько криворукий разработчик. Если разработчик, отдавая динамический контент, не способен корректно обработать заголовки If-Modified-Since/If-None-Match, то это сугубо его сексуальные проблемы.

d9d9 ★★★ ()
Ответ на: комментарий от Eddy_Em

а тема состояла из основного сообщения и динамически создающихся iframe'ов

Это сильно нагрузит сайт.

Вместо одного запроса к серверу — серия в N (20..50..100) запросов.

Вместо одного запроса к БД (SELECT … FROM posts WHERE topic_id = … ORDER … LIMIT …) — 20…50…100 запросов.

страничка ЛОРа грузится чуть ли не по полчаса!

Поставь число сообщений на страницу поменьше :) И учти, что при разбивке на несколько запросов грузиться будет дольше и с сетевой точки зрения. Вместо установления одного соединения — 20..50..100 последовательных.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

Вместо одного запроса к серверу — серия в N (20..50..100) запросов.

А на сервере - кэширующий прокси.

Вместо одного запроса к БД (SELECT … FROM posts WHERE topic_id = … ORDER … LIMIT …) — 20…50…100 запросов.

А хранить не в БД, а в файлах.

Поставь число сообщений на страницу поменьше

5?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

А на сервере - кэширующий прокси.
А хранить не в БД, а в файлах.

Один фиг — серия запросов. И это — узкое место сервера. Вместо небольшой разгрузки CPU сервера получишь высокую нагрузку на IO.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

Один фиг — серия запросов. И это — узкое место сервера.

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


динамически создающихся iframe'ов

Ифреймы? Я думал на дворе 2012й год. Печалька.

d9d9 ★★★ ()
Ответ на: комментарий от d9d9

Ифреймы? Я думал на дворе 2012й год. Печалька.

Можешь предложить что-нибудь лучше?

Только iframe способны отображать кучу разрозненных веб-страниц на одной. Только так можно улучшить кэширование.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Можешь предложить что-нибудь лучше?
Только iframe способны отображать кучу разрозненных веб-страниц на одной. Только так можно улучшить кэширование.

Т.е. про XMLHttpRequest ты не слышал? Про LocalStorage? Тоже не? А для того, чтобы улучшить кеширование, начни с ответа 304 на не изменившийся динамический контент :)

d9d9 ★★★ ()
Ответ на: комментарий от d9d9

Т.е. про XMLHttpRequest ты не слышал?

Надеюсь хоть ты пошутил... Ты же не прделогаешь грузить каждый пост темы на ЛОРе отдельным запросом, пусть даже через XMLHttpRequest

Suntechnic ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Использую. И как их по-твоему кэшировать?

Принцип работы тот же что и у ифрейма. Если страница отдает и обрабатывает заголовки кеширования корректно, он будет брать результаты из кеша. Максимум - спросит сервер «а не изменилось ли содержимое с момента..». Вообще - это элементарно мониторится средствами разработчика браузера или чем-то типа fiddler'а.

Это - вообще не то.

Что значит «не то»? Есть масса данных, которые меняются не часто и не обязательно при каждой загрузке страницы их запрашивать. Да и элементарно организовать кеш вручную на клиенте, добавив к данным timestamp/hash.

d9d9 ★★★ ()
Ответ на: комментарий от d9d9

Принцип работы тот же что и у ифрейма

Можешь тыкнуть меня в мануал squid'а, чтобы подтвердить, что такие запросы будут кэшироваться? А то я даже не могу научиться яваскрипты кэшировать...

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

Local Storage годится лишь для малого объема данных - мегабайтное содержимое сотен веб-страниц никто в них хранить не будет.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Suntechnic

Надеюсь хоть ты пошутил... Ты же не прделогаешь грузить каждый пост темы на ЛОРе отдельным запросом, пусть даже через XMLHttpRequest

Я не вчитывался в предложенную реализацию. Просто ифреймы уже давно умерли и для подгрузки данных есть более современные технологии. Грузить, естественно, списком. Узкий канал? Кешировать в LocalStorage и загружать только изменения. Получать ответ 304 без body если нет изменений.

d9d9 ★★★ ()
Ответ на: комментарий от Eddy_Em

Можешь тыкнуть меня в мануал squid'а, чтобы подтвердить, что такие запросы будут кэшироваться? А то я даже не могу научиться яваскрипты кэшировать...

Я не пользуюсь proxy. Тут проблема в корректных заголовках как запроса так и ответа.


Local Storage годится лишь для малого объема данных

А ты думаешь ты читаешь многомегабайтные тексты? Кешируй только контент в виде json. Отрендерить на клиенте можно с помощью, например, knockoutjs.

d9d9 ★★★ ()
Ответ на: комментарий от d9d9

Я не пользуюсь proxy

А у меня дома без squid'а жизни вообще не будет!

А ты думаешь ты читаешь многомегабайтные тексты? Кешируй только контент в виде json. Отрендерить на клиенте можно с помощью, например, knockoutjs.

Не надо изобретать велосипед, когда есть squid. Даже если у клиента на домашнем компьютере прокси не стоит, он стоит у провайдера. Так что - все ОК.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от KRoN73

2 — из логики работы веб-серверов

Вообще, по логике вещей, всё зависит от того, как задать ключ.

Например, для nginx так:

fastcgi_cache_key $request_method|$host|$request_uri

после чего запросы с GET будут отлично кешироваться.

sjinks ★★★ ()
Ответ на: комментарий от Eddy_Em

А то я даже не могу научиться яваскрипты кэшировать...

А что с ними не то? Например, для этой страницы для всех js сервер выдал 304 Not Modified.

А браузер шлёт заголовки If-Modified-Since/If-None-Match?

sjinks ★★★ ()
Ответ на: комментарий от d9d9

Получать ответ 304 без body если нет изменений.

А это другой больной вопрос... На самом деле переделываю приложение которое работало до этого без БД. Т.е. все хранилось в fs куда сохранялись в файлы структуры dict. Для его задач было нормально - там максимум 200 записей by dedsign. Но понадобилось другое приложение и было решено воспользоваться старым кодом, что бы хотя бы собственные велосипеды не изобретать. А проверяло оно раньше неизменность данных так - функция чтения из файла добавляла его в список при генерации страницы. После отправки страницы, список это сохранялся. При обращении с тем же запросом, проверялось время модификации этих файлов из списка и если ничего не поменялось - отвечалось 304.

Сейчас кэш самого приложения и определение неизменности страницы вырублено вообще. Как реализовывать в условиях работы с БД не представляю еще. А какие есть способы. Где б чего почитать?

Suntechnic ★★★★★ ()
Ответ на: комментарий от Suntechnic

Как реализовывать в условиях работы с БД не представляю еще. А какие есть способы. Где б чего почитать?

Самое простое - брать отрендеренный блок основного контента, вычислять хеш от него и засовывать в e-tag. Потом проверять If-None-Match. Таким макаром все равно откуда берутся данные.

Можно в бд хранить дату последнего изменения и использовать её в If-Modified-Since или в e-tag. Это, также позволяет получать список изменений начиная с какой-то даты и объединять на клиенте.

d9d9 ★★★ ()
Ответ на: комментарий от d9d9

Самое простое - брать отрендеренный блок основного контента, вычислять хеш от него и засовывать в e-tag. Потом проверять If-None-Match. Таким макаром все равно откуда берутся данные.

Гы. Типа, логика: получили от клиента запрос IMS. Сгенерировали страницу. Посчитали хэш. Проверили. Если не поменялся — послали, поменялся — отдали?

Так тут бутылочное горлышко не отдача страницы, а её генерация :)



Всегда как есть проверял, по дате модификации состояния объекта… У каждого отдаваемого объекта есть такой атрибут. Если меняется сам объект или что-то, от чего он зависит, если это контейнер, обновляется соответствующий его атрибут. И при запросе IMS ничего можно не генерировать, сверив только даты.

KRoN73 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.