Донецкий техникум промышленной автоматики

Правильна відповідь сервера: заголовки Last-Modified і if-modified-since

  1. Правильна відповідь сервера
  2. Як налаштувати 304 і 200 відповіді сервера?
  3. Заголовки Last-Modified і if-modified-since
  4. Помилки при вказівці дати останнього зміни
  5. if-modified-since

Замітка: активована адаптивна версія сайту, яка автоматично підлаштовується під невеликий розмір Вашого браузера і приховує деякі деталі сайту для зручності читання. Приємного перегляду!

08.06.2013

Привіт шановні читачі блогу Site on! Ми продовжуємо тему внутрішньої оптимізації сайту , Одного з найважливіших чинників SEO. Ця стаття торкнеться те, що можна назвати тонкощами внутрішньої оптимізації, так як мова піде про коді відповіді, який отримають пошукові системи і відвідувачі у відповідь на їх звернення до сторінки.

Правильна відповідь сервера

Незважаючи на те, що це досить дрібна деталь при побудові і оптимізації сайту в цілому, однак вона дуже важлива! А саме важливо, щоб сторінка, на якій не було змін з останнього візиту робота або людини віддавала 304 код, який означає, що сторінка залишилася без змін. Коли сервер віддає клієнту цей код, то виконання всіх PHP сценаріїв на сторінці навіть не починається, замість цього сторінка завантажується з кешу, що значно знижує навантаження на сервер і прискорює завантаження сторінки у користувача.

Таким чином, налаштувавши правильні відповіді нашого сервера, ми вбиваємо одразу як мінімум п'ять зайців:

  • Прискорюємо завантаження сторінки для відвідувачів (людей).
  • Знижуємо навантаження на сервер.
  • У пошуковій видачі буде (для Яндекса точно) показуватися дата останнього оновлення сторінки, що може привернути увагу користувача, особливо, якщо дата недавня.
  • Сторінки сайту братимуть участь в сортуванні пошукових систем за датою.
  • Значно прискорюємо індексування сайту пошуковими системами!

Чомусь для мене останній пункт здається найсолодшим (так як впливає на SEO і підвищує довіру до вашого сайту у пошукових систем), хоча без сумніву інші пункти теж надзвичайно важливі.

Як налаштувати 304 і 200 відповіді сервера?

Ми вже сказали про те, що у відповідь на запит до постійних сторінок сервер повинен віддавати 304 Not Modified, а який код сервер повинен віддавати, якщо клієнт звертається до сторінці перший раз або звертається до нової сторінці? У таких випадках сервер повинен віддавати статус 200 OK. Спеціально даний код посилати не потрібно, якщо зі сторінкою все в порядку, то вона завжди видає 200.

Тому нам потрібно подбати тільки про 304 коді, так як його, сервер без нашого втручання не було пошле. Для цього нам допоможе веб-орієнтована мова PHP , А також заголовок Last-Modified і запит if-modified-since.

Заголовки Last-Modified і if-modified-since

Last-Modified - це заголовок, який ми посилаємо за допомогою PHP, даний заголовок містить точний час останньої зміни сторінки (в секундах). Для цього використовується загальноприйнята міра вимірювання часу: Unix Time Stamp.

Unix time stamp - це число секунд, що пройшли з початку епохи Юнікс 1 січня 1970 року. На момент написання цієї пропозиції Unix time stamp дорівнює 1370597447 секунд - це 07.06.2013 9:30:47 GMT (+00: 00).

Тобто все, що нам потрібно робити, це всього лише посилати PHP заголовок з інструкцією Last-Modified і потрібної датою:

header ( 'Last-Modified:' .gmdate ( 'D, d MYH: i: s', $ last_modified_time). 'GMT');

Де header - це конструкція для відправки HTTP заголовка, Last-Modified - то, що ми відправляємо і відразу після двокрапки йде його значення:

gmdate ( 'D, d MYH: i: s', $ last_modified_time). ' GMT '.

У ролі значення Ласт-модіфайд виступає функція gmdate (), яка містить придуману мною змінну $ last_modified_time (ви можете назвати як завгодно). У змінній $ last_modified_time і міститься час останньої зміни в форматі Unix Time Stamp, а функція gmdate () служить нам для того, щоб привести дату в належний вигляд (час за Гринвічем).

Для наочності ось вам приклад: якщо ми в функцію gmdate () покладемо значення 1365003142, то на виході отримаємо: Wed, 03 Apr 2013 15:32:22.

Тепер, коли ми дізналися, як відбувається весь процес, може виникнути питання: «Це що, для кожній сторінці нам вручну потрібно вказувати час останньої зміни?». Відповідь: «Так!». Особисто я роблю саме так - вручну, найнадійніший варіант. Однак конкретно для даного блогу я все передбачив, наприклад, якщо з'являється новий коментар на сторінці, то в змінну $ last_modified_time заноситься час додавання цього коментаря, це зроблено для того, щоб пошукові системи змогли проіндексувати нові коментарі і знали, що сайт «живий» . Кожен сайт індивідуальний і вам доведеться придумати свій власний алгоритм за вказівкою дати останнього зміни сторінки, або завжди вказувати її вручну.

Ще раз підкреслю, у мене алгоритм такий:

1) я вказую дату створення матеріалу вручну, якщо я міняю щось в статті (помилки або дописую), то потім я знову-таки вручну вписую новий час останнього оновлення.

2) Якщо відвідувач додає коментар, то в змінну $ last_modified_time автоматично, без мого відома заноситься час додавання коментарів, так як фактично це і буде датою останньої зміни сторінки.

Чого я не врахував: в правій колонці сайту у мене знаходяться свіжі статті, рекомендовані і топ-10. Вони змінюються постійно і при цьому одночасно для всіх сторінок. Якби я при кожній зміні правої колонки сайту міняв (автоматично або вручну - не важливо) дату останньої зміни сторінки, то загубився б весь сенс цієї дії. Я вирішив, що ці зміни відстежувати і враховувати при вказівці $ last_modified_time не варто, так як вони не несуть в собі користі для SEO.

Як я вже писав, я не можу вказати вам, як саме автоматизувати дату останньої зміни сторінки, але я скажу вам, як цього робити НЕ потрібно!

Помилки при вказівці дати останнього зміни

Перше що може прийти в голову більшості людей, це в заголовку посилати дату внесення останніх змін з вмістом сторінки. Особисто у мене тексти статей лежать в файлах, а не в базі даних, так що для мене такий спосіб міг би здатися відмінним виходом, щоб не вводити кожен раз Unix Time Stamp вручну. Але немає! Більшість хостингів, а може навіть все, за дату внесення останніх змін беруть дату його створення, вони не враховують наступні його зміни.

Я думаю, наслідки в такому випадки вам зрозумілі. Один популярний український хостинг провайдер (і думаю не він один) в своєму FAQ пише щось на зразок: «Замість дати внесення останніх змін використовуйте функцію time (), яка повертає поточний час в форматі Unix time stamp». Ось так абсурд! Це ж просто на місці застрелиться! І цей хостинг-провайдер вважається «одним з кращих», після того як я це прочитав, я відразу ж перехотів ставати їх клієнтом.

Це просто анти-SEO, самі подумайте, заходить до вас на сторінку поісковічёк і дивиться: «Ух ти ж-ка! Останнім часом зміни сторінки було тільки що, ось це я вгадав коли прийти, клас! ». Заходить він через пару днів на цю ж саму сторінку: «Диви, знову тільки що змінилася, ось це збіг ... Стривайте, а чому я не бачу ніяких змін? Гаразд, прийду іншим разом ». Приходить знову: «Ну немає мужики, це вже не смішно, довіряти вам точно не можна». Ось така ось казочка :)

А потім люди дивуються, чому результати в пошуковій видачі не такі як хотілося б, та тому що до вашого сайту втрачається банальне довіру (trust). Прям як в казці "Про пастуха і вовків".

Отже, з основними помилками розібралися: не можна вказувати поточний час і не раджу вказувати час редагування файлу. Тепер продовжимо розбирати як це все працює.

Налаштувати відсилання заголовків Last-Modified це рівно 1/3 справи, нам ще належить: зробити відповідь на запит if-modified-since і включити кешування сторінки. Обидва ці дії не займуть багато часу і рядків коду.

if-modified-since

if-modified-since - це запит клієнта до вашого сервера, в ньому клієнт запитує: «чи не змінилася сторінка з мого останнього візиту?». Якщо сторінка не змінилася, то ми повинні зупинити виконання подальшого завантаження сторінки командою:

die

При цьому тіло сторінки не повинно почати отрісовиваться, це все відбувається ДО першого виведення чогось на сторінку! Разом з цим необхідно повернути клієнту відповідь сервера 304 Not Modified, тим самим сказавши, що сторінку потрібно взяти з кешу. Давайте відразу до справи:

if (isset ($ _ SERVER [ 'HTTP_IF_MODIFIED_SINCE']) && strtotime ($ _ SERVER [ 'HTTP_IF_MODIFIED_SINCE'])> = $ last_modified_time) {header ( 'HTTP / 1.1 304 Not Modified'); die; } Header ( 'Last-Modified:' .gmdate ( 'D, d MYH: i: s', $ last_modified_time). 'GMT');

Отже, в першому рядку ми за допомогою умовного оператора PHP (if) перевіряємо, чи прийшов до нашого серверу запит HTTP_IF_MODIFIED_SINCE, а також відразу перевіряємо число секунд у отриманому HTTP_IF_MODIFIED_SINCE більше, ніж в $ last_modified_time чи ні? Якщо більше, значить дата останнього візиту клієнта пізніше, ніж дата останнього зміни сторінки, звідси робимо чисто логічний висновок, що сторінка не змінилася, а значить другим рядком відправляємо відповідь сервера 304 Not Modified і 3 рядком вбиваємо (припиняємо) виконання всіх сценаріїв на сторінці. Іншими словами припиняємо її завантаження.

Якщо ж клієнт не послав нам запит HTTP_IF_MODIFIED_SINCE або його останній візит виявився раніше, ніж дата останнього зміни сторінки, то ми (за замовчуванням) віддаємо код 200 ОК і п'ятим рядком посилаємо йому Актуальні дату зміни сторінки, замість тієї, що була у нього.

Про IF_MODIFIED_SINCE і як влаштований код розповів вам все що потрібно, крім того, що робить функція strtotime ():

strtotime ($ _ SERVER [ 'HTTP_IF_MODIFIED_SINCE'])

Уважний і кмітливий читач уже міг здогадатися, що ця функція конвертує звичайну дату в Unix time stamp, так як змінну $ last_modified_time ми задаємо саме в ньому, а тому для порівняння нам необхідно привести все до спільного знаменника загальній системі вимірювання.

І останнє, нам залишається тільки включити кешування, це робиться за допомогою наступних рядків:

header ( "Cache-Control: public"); header ( "Expires:". date ( "r", time () + 10800));

Де число 10800 цей час (в секундах) на яке ми хочемо закешовану сторінку, тобто в даному прикладі на 3 години.

І як завжди для тих, хто нічого не зрозумів викладаю все повністю, як це влаштованої у мене на блозі:

<? Php header ( "Cache-Control: public"); header ( "Expires:". date ( "r", time () + 10800)); if (isset ($ _ SERVER [ 'HTTP_IF_MODIFIED_SINCE']) && strtotime ($ _ SERVER [ 'HTTP_IF_MODIFIED_SINCE'])> = $ last_modified_time) {header ( 'HTTP / 1.1 304 Not Modified'); die; / * Вбили все, що нижче * /} header ( 'Last-Modified:' .gmdate ( 'D, d MYH: i: s', $ last_modified_time). 'GMT'); ?> <! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Transitional // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml" xml: lang = "ru-ru" lang = "ru-ru" dir = "ltr"> І пішла поїхала вся інша частина сторінки

Думаю, ви могли помітити, що вся ця історія з Ласт-модіфайд є аналогом тега в sitemap.xml - lastmod . Так ось lastmod носить ознайомчо-рекомендаційний характер, а з відповідями вашого сервера ніхто не сперечатиметься. Природно, не рідкість, коли lastmod в карті сайту відрізняється від заголовка Ласт-Модіфайд, проте з цього моменту вони повинні бути у вас однакові! Адже ми тепер з вами яку науку вивчили, не для того щоб уподібнюватися горе-вебмастерам, які далі sitemap.xml не просунулися.

Особисто я в даний момент взагалі не користуюся тегом lastmod в своїх картах сайтах, можливо, пізніше я перегляну свої дії, але поки що не бачу сенсу бути настільки скурпулезно, маючи правильні заголовки Last-Modified :)

І наостанок, перевірити коректність Last-Modified і if-modified-since ви можете за допомогою цього сервісу: клік .

Дякую за вашу увагу, особлива подяка постійно зростаючої кількості передплатників, для мене це найбільший стимул писати в блог частіше. Так що хто ще не підписався на вихід нових статей, ласкаво просимо!

Будь ласка, оцініть цю статтю
Середня оцінка: 4.46 з 5 (голосів: 37)
Стаття виявилася вам корисною? Підпишіться, щоб не пропустити нові!
Ви можете допомогти розвитку проекту, зробивши всього 1 клік:
Дякуємо!Як налаштувати 304 і 200 відповіді сервера?
Стривайте, а чому я не бачу ніяких змін?
GMT'); ?