Avila BeachAvila Beach // 2010-09-18

Вчора прикрутив оновлення списку останніх повідомлень з форуму на Теревенях (посилання оновити).

Тут я спробую описати, як швидко і без проблем прикрутити собі на сайт подібне.

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

Що в мене було раніше.
Був скрипт, який формував таблицю Останні повідомлення на форумі. Підключався він ось так:
include "forum/latest_posts.php";

Щоб отримати останні повідомлення з форума потрібно було оновити сторінку. Але це займає багато часу (завантаження + опрацювання браузером).

Тепер про Ajax.

Основний елемент JavaScript, на якому це все працює – XMLHttpRequest.
Але в різних браузерах він реалізований по різному. На відміну від інших в Microsoft Internet Explorer це все реалізовано через ж… ActiveX. Тому з ним була деяка морока.

Ось функція на JavaScript, що визначає браузер, і повертає потрібний елемент XMLHttpRequest

function createXMLHttp()
{
  if (typeof XMLHttpRequest != "undefined")
    return new XMLHttpRequest();
  else if (window.ActiveXObject)
  {
    var aVersions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", "Microsoft.XMLHttp"];
    for (var i = 0; i < aVersions.length; i++)     {       try       {         var oXmlHttp = new ActiveXObject(aVersions[i]);         return oXmlHttp;       }       catch (oError) {}     }   }   throw new Error("XMLHttp object could be created."); }

Як видно з коду основна морока - визначити, яка версія браузера в користувача.
Далі просто повертаємо потрібний елемент.

Наступна функція викликає функцію createXMLHttp, отримує за допомогою нього дані і показує їх на сторінці:

function submitForm()
{
  document.getElementById('updating').style.display='inline';
  document.getElementById('update').style.display='none';
  var req = createXMLHttp();
  req.onreadystatechange = function()
  {
    if(req.readyState == 4)
      if(req.status == 200)
        document.getElementById("result").innerHTML=req.responseText;  
  };
  req.open("GET", "forum/latest_posts_ajax.php?id=" + Math.random(), true);
  req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  req.setRequestHeader('Accept-Language', 'uk');
  req.send(null);
}

Цей рядок: if(req.readyState == 4) означає що дані отримані, а
цей: if(req.status == 200) що скрипт повернув 200 код, тобто все гаразд.

Конструкція: document.getElementById("result").innerHTML=req.responseText; вставляє в елемент сторінки <div id='result'>...</div> отримані дані.

Поміщаємо все це в окремий файл (наприклад, ось так) а на сторінці прописуємо:
<script type="text/javascript" src="./mkportal/templates/tereveni/ajax.js"></script>

Тепер розглянемо файл forum/latest_posts_ajax.php
В принципі там немає нічого особливого, це звичайний скрипт експорту останніх повідомлень з форуму IPB, написаний на php. Генерує він ось таке
Для нас важливі тільки ось ці рядки:
@header('Content-Type: text/plain; charset=utf-8');
Це ми кажемо браузеру, що дані є звичайним текстом в кодуванні utf-8 (юнікод).
Я спочатку пробував видавати все в windows-1251 (в мене і сайт, і база в цьому кодувані).
В Опері, ВогнеЛисі все працювало просто прекрасно. А от Інтернет Експлорер видавав закарлючки.
Виявилось що Експлореру все рівно, яке кодування вказане, він все рівно використовую utf-8.
Для перекодування тексту з windows-1251 в UTF-8 використовуйте код:
echo iconv("windows-1251", "UTF-8", $echo);
(в змінній $echo міститься вже згенерована таблиця)

Тепер останній штрих - розміщення посилання оновити. Ну тут все просто:
<a href='javascript:submitForm();'>оновити</a>

Як це все працює можна глянути тут

Важливо: Поданий код реально працює, якщо у вас він чомусь не захотів працювати - перевірте, чи увімкнена підтримка JavaScript (не Java!!!) в браузері, або, якщо не дай Бог ви користуєтесь ІЕ, ввімкнений ActiveX.
Якщо все рівно не захотіло працювати - Ґуґл в поміч (по словах Ajax або XMLHttpRequest)