Header content type text xml charset windows 1251

Здравствуйте! Имеется следующий код для обработки xml: section->tour as $tour) { echo "

". $tour->resort. "&l...

Здравствуйте!

Имеется следующий код для обработки xml:

<?php 
$vitrina =  simplexml_load_file('URL');
foreach ($vitrina->section->tour as $tour) {
echo "<h2>". $tour->resort. "</h2>";
echo "<p>Отель: ". $tour->hotel. "</p>";
echo "<p>Вылет: ". $tour->departure. "</p>";
echo "<p><a href=". $tour->bookurl. ">Забронировать</a></p>";
} 
?>

При отображении результата на сайте — ошибка кодировки, кириллица выводится кракозябрами… Пробовал указывать кодировку в теге meta — безрезультатно. Подскажите, пожалуйста, как сделать это правильно.

Oceinic's user avatar

Oceinic

2,3241 золотой знак15 серебряных знаков35 бронзовых знаков

задан 30 авг 2012 в 15:20

Casimir's user avatar

2

Понятно что ничего не понятно. В какой кодировке PHP-исходники, в какой XML, какие HTTP-заголовки отдаются, есть ли AddDefaultCharset в .htaccess, что в мете, что на скриншоте в браузере?

ответ дан 30 авг 2012 в 15:28

Попробуй поменять кодировку в контент-тип

header("Content-type: text/xml;charset=window-1251");

ответ дан 30 авг 2012 в 16:33

ViruSkin's user avatar

ViruSkinViruSkin

1,2676 серебряных знаков12 бронзовых знаков

За последние 24 часа нас посетили 10152 программиста и 1254 робота. Сейчас ищет 371 программист …


  1. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    Здравствуйте. Есть определенный $url, выдает данные в формате xml. Хочу через simplexml_load_file получить xml объект по запросу на этот $url, но ничего не получается, ни ошибок, ничего…
    Скрипт ниже:

    1. header(‘Content-type: text/xml;charset=windows-1251’);
    2. //header(‘Content-Type: application/json;charset=windows-1251’);
    3. header(‘Access-Control-Allow-Origin: *’);
    4. ini_set(‘display_startup_errors’, TRUE);
    5.        ‘header‘=>»Accept: application/xmlrn» .
    6.                  «Authorization: ключrn»),
    7.      ‘ssl‘ => array(‘verify_peer‘=>false, ‘allow_self_signed‘ => true)
    8.    $context = stream_context_create($options);
    9.    $file = file_get_contents($url, false, $context);
    10.    $file = simplexml_load_file($file);

    Если изменить MIME тип на header(‘Content-Type: application/json;charset=windows-1251’); file_get_contents получит данные в тегах html.
    Как получить данные в формате xml?


  2. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    Спасибо, заменил на simplexml_load_string. Пишет, что документ пуст…

    This page contains the following errors:
    error on line 1 at column 1: Document is empty
    Below is a rendering of the page up to the first error.


  3. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    var_dump показывает, что $file содержит нужную информацию, но $xml ==false. Ни ошибок, ничего…

    1.     header(‘Content-Type: application/json;charset=windows-1251’);
    2.     header(‘Access-Control-Allow-Origin: *’);
    3.     ini_set(‘display_startup_errors’, TRUE);
    4.         ‘header’=>«Accept: application/jsonrn« .
    5.                   «Authorization: keyrn«),
    6.       ‘ssl’ => array(‘verify_peer’=>false, ‘allow_self_signed’ => true)
    7.     echo «Failed loading XML: «;
    8.         echo «<br>», $error->message;


  4. Drunkenmunky

    Drunkenmunky
    Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.325
    Симпатии:
    258

    Сохраните содержимое $file в файл.
    И проверьте его валидатором.
    Кроме того, вы всё еще используете simplexml_load_file а не *string


  5. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    1.     header(‘Content-Type: application/json;charset=windows-1251’);
    2.     ini_set(‘display_startup_errors’, TRUE);
    3.     $url = ‘https://adress/outtype=xml’;
    4.         ‘header’=>«Accept: application/xmlrn« .
    5.                   «Authorization: secretKeyrn«),
    6.       ‘ssl’ => array(‘verify_peer’=>false, ‘allow_self_signed’ => true)
    7.     $xml = XMLReader::open(‘test.xml’);
    8.     $xml->setParserProperty(XMLReader::VALIDATE, true);

    результат:

    Файл test.xml содержит html код


  6. Drunkenmunky

    Drunkenmunky
    Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.325
    Симпатии:
    258


  7. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    1. <!DOCTYPE HTML PUBLIC «-//W3C//DTD HTML 4.01 Transitional//EN»>
    2. <META http-equiv=»Content-Type» content=»text/html; charset=Windows-1251″>
    3. <META name=»GENERATOR» content=»IBM WebSphere Studio»>
    4. <META HTTP-EQUIV=»Pragma» CONTENT=»no-cache»>
    5. <META HTTP-EQUIV=»Expires» CONTENT=»-1″>
    6. <TITLE>ПВ — Паспорт  а </TITLE>
    7. <link rel=»stylesheet» type=»text/css» href=»asupv.css»>
    8. <SCRIPT language=»JavaScript» SRC=»asupv.js»></SCRIPT>
    9. <BODY style=»overflow: visible;» >
    10. <!— <p class=»DebugMsg»> remHT = {6={tekVidM=0003, tekKodName=прохождение ДОК, tekKorPr=196, tekKorPrFName= ный участок Москва-Ярославская, tekTimen=08:00:00, tekMestoDorName=ОКТ  , tekKor=0020, tekTimek=18:00:00, tekKorT=00:00:00, tekKorPrName=ЛВЧ-3, tekMestoFName= ное   Санкт-Петербург Главный, tekKorPrDorName=МСК  , tekTable=remont, tekDPR=, tekMestoName=ВЧД-08, tekKod=0013, tekKorFName=, tekDatan=2009-10-27, tekProbeg=0, tekMesto=145, tekKorD=2021-08-17, tekKorName=, tekDatak=2009-10-31, tekInv=31124, tekModern=, tekKodFName=прохождение ДОК}, 5={tekVidM=0003, tekKodName=ДР, tekKorPr=160, tekKorPrFName= ный участок Санкт-Петербург- ий, tekTimen=12:00:00, tekMestoDorName=ОКТ  , tekKor=, tekTimek=12:00:00, tekKorT=00:00:00, tekKorPrName=ЛВЧ-СПБ_МОСК, tekMestoFName= ое  ное   СПб- ий, tekKorPrDorName=ОКТ  , tekTable=remont, tekDPR=, tekMestoName=ЛВЧД-8, tekKod=0005, tekKorFName=, tekDatan=2014-05-02, tekProbeg=666082, tekMesto=145, tekKorD=2021-08-17, tekKorName=, tekDatak=2014-05-02, tekInv=31124, tekModern=, tekKodFName= вской  }, 4={tekVidM=0003, tekKodName=КР-1, tekKorPr=144, tekKorPrFName= ое  ное   Москва, tekTimen=08:00:00, tekMestoDorName=ОКТ  , tekKor=, tekTimek=18:00:00, tekKorT=19:48:44, tekKorPrName=ЛВЧД-МОСКВА_ОКТ, tekMestoFName= ое  ное   Москва, tekKorPrDorName=ОКТ  , tekTable=vu36_remont, tekDPR=0009, tekMestoName=ЛВЧД-МОСКВА_ОКТ, tekKod=0002, tekKorFName=, tekDatan=2019-12-20, tekProbeg=870171, tekMesto=144, tekKorD=2020-01-12, tekKorName=, tekDatak=2020-01-11, tekInv=31124, tekModern=    , tekKodFName= ьный   первого объёма}, 3={tekVidM=0003, tekKodName=ТО-3, tekKorPr=212, tekKorPrFName=ЛВЧД-Киров, tekTimen=08:00:00, tekMestoDorName=ГОР  , tekKor=, tekTimek=16:00:00, tekKorT=09:54:36, tekKorPrName=ЛВЧД-КИРОВ, tekMestoFName=ЛВЧД-Киров, tekKorPrDorName=ГОР  , tekTable=vu36_remont, tekDPR=0009, tekMestoName=ЛВЧД-КИРОВ, tekKod=0006, tekKorFName=, tekDatan=2021-01-14, tekProbeg=990639, tekMesto=212, tekKorD=2021-01-15, tekKorName=, tekDatak=2021-01-14, tekInv=31124, tekModern=    , tekKodFName=техническое обслуживание -3}, 2={tekVidM=0003, tekKodName=ТО-2, tekKorPr=304, tekKorPrFName= ный участок Хабаровск, tekTimen=12:00:00, tekMestoDorName=Д-В  , tekKor=, tekTimek=12:00:00, tekKorT=00:00:00, tekKorPrName=ЛВЧ-1, tekMestoFName= ный участок Хабаровск, tekKorPrDorName=Д-В  , tekTable=remont, tekDPR=, tekMestoName=ЛВЧ-1, tekKod=0020, tekKorFName=, tekDatan=2021-09-21, tekProbeg=1008932, tekMesto=304, tekKorD=2021-09-22, tekKorName=, tekDatak=2021-09-21, tekInv=31124, tekModern=, tekKodFName=техническое обслуживание — 2}, 1={tekVidM=0003, tekKodName=ТО-1, tekKorPr=196, tekKorPrFName= ный участок Москва-Ярославская, tekTimen=23:00:00, tekMestoDorName=МСК  , tekKor=, tekTimek=23:00:00, tekKorT=00:00:00, tekKorPrName=ЛВЧ-3, tekMestoFName= ный участок Москва-Ярославская, tekKorPrDorName=МСК  , tekTable=remont, tekDPR=, tekMestoName=ЛВЧ-3, tekKod=0022, tekKorFName=, tekDatan=2021-10-23, tekProbeg=1034757, tekMesto=196, tekKorD=2021-10-23, tekKorName=, tekDatak=2021-10-23, tekInv=31124, tekModern=, tekKodFName=техническое обслуживание перед отправкой в рейс}, 0={tekVidM=0003, tekKodName=ТОР, tekKorPr=281, tekKorPrFName= ный участок Новосибирск- Главный, tekTimen=01:00:00, tekMestoDorName=З-СИБ, tekKor=, tekTimek=03:00:00, tekKorT=09:05:50, tekKorPrName=ЛВЧ-7, tekMestoFName= ое  ное   Новосибирск, tekKorPrDorName=З-СИБ, tekTable=vu36, tekDPR=0009, tekMestoName=ЛВЧД-7, tekKod=0007, tekKorFName=, tekDatan=2021-12-08, tekProbeg=1069427, tekMesto=2513, tekKorD=2021-12-09, tekKorName=, tekDatak=2021-12-08, tekInv=31124, tekModern=    , tekKodFName=текущий отцепочный  }, 7={tekVidM=0004, tekKodName=постройка, tekKorPr=160, tekKorPrFName= ный участок Санкт-Петербург- ий, tekTimen=12:00:00, tekMestoDorName=, tekKor=, tekTimek=12:00:00, tekKorT=00:00:00, tekKorPrName=ЛВЧ-СПБ_МОСК, tekMestoFName=АОЗТ  МАШ, tekKorPrDorName=ОКТ  , tekTable=remont, tekDPR=, tekMestoName= МАШ, tekKod=0001, tekKorFName=, tekDatan=2005-12-28, tekProbeg=0, tekMesto=6, tekKorD=2021-08-17, tekKorName=, tekDatak=2005-12-28, tekInv=31124, tekModern=, tekKodFName=постройка  а}}</p>—>
    11. <TR><TD align=»right» width=»100%»>
    12. Дата: 16.12.2021&nbsp; 15:54:00
    13. <DIV class = «onMetallDiv» id = «OnMetall» style = «display: none»>
    14. <DIV class=»nvDiv» id = «DivNv»>
    15. <h1>Электронный паспорт  а №&nbsp;00152280&nbsp;<a
    16.     class=»NVLink» href=’javascript:ShowHistory(«nv»,»00152280″)’ title =»История»
    17.     ><IMG alt=»История» src=»image/view.gif» border=»0″></a>
    18.     <a class=»NVLink» href=’javascript:showABDVPP();’ title=»Справка о паспортных данных и эксплуатационных ресурсах  а РФ из АБД ВПП»
    19.     ><IMG alt=»Справка о паспортных данных и эксплуатационных ресурсах  а РФ из АБД ВПП» src=»image/db_rus.png» border=»0″ width=»24″ height=»24″></a>

    Вот его часть. Выглядит как исходный код страницы.


  8. Drunkenmunky

    Drunkenmunky
    Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.325
    Симпатии:
    258

    Значит вы что-то не то импортируете. Правильно?
    От PHP-то вы что хотите?
    Подайте ему корректные данные и всё будет.


  9. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    Вопрос в том как это сделать.
    Если перейти по ссылке (простите, но она вырезана из кода) просто через браузер, открывается именно структура xml, все корректно.

    Если я шлю header(‘Content-Type: text/xml); (строка 2), получаю ошибку:

    1. This page contains the following errors:
    2. error on line 2 at column 1: Extra content at the end of the document
    3. Below is a rendering of the page up to the first error.

    Или ту, что выше.
    Хоть какие-то данные получается вытащить только в виде исходного кода страницы.


  10. Drunkenmunky

    Drunkenmunky
    Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.325
    Симпатии:
    258

    Значит что-то не передаете. Куки скорее всего, с авторизацией например. А может сам факт их отсутствия играет роль.
    Замените file_get_contents() на curl()


  11. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    1.     ini_set(‘display_startup_errors’, TRUE);
    2.     $url = ‘https://site.ru/nvag=00152280&datesel=yes&sdate=16.12.2021&ch=15&min=54&stime=15%3A54&outtype=xml
    3.         ‘header’=>«Accept: application/xmlrn« .
    4.                   «Authorization: keyrn«)
    5.         curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER[‘DOCUMENT_ROOT’].‘/tools/cookie.txt’);
    6.         curl_setopt($ch, CURLOPT_COOKIE, $_SERVER[‘DOCUMENT_ROOT’].‘/tools/cookie.txt’);
    7.         if (isset($error_msg)) echo «$error_msg«;

    Получаю ошибку The requested URL returned error: 400 Bad Request, устал с ней биться
    Я в очередной раз иссяк, подскажите, куда копать теперь?

    Сайт, с которого пытаюсь получить xml, требует авторизации и спец ключа. Возможно это важно. Логинпассключ в наличии, корректны. Через веб браузер нужнаня страница открывается без проблем


  12. Drunkenmunky

    Drunkenmunky
    Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.325
    Симпатии:
    258


  13. filip

    filip
    Активный пользователь

    С нами с:
    13 окт 2018
    Сообщения:
    18
    Симпатии:
    0

    @Drunkenmunky , спасибо за помощь. Вопрос решен. Код из первого поста рабочий. Проблема была в знаке n в адресе ссылки,

    https://site.ru/assdfa=23424 n &outtype=xml
    Скрипт просто не считывал конец ссылки, и не выводил требуемые данные в формате xml.

Каждый раз при отправке формы на сервер, страничка полностью перезагружается, на что уходит трафик и время. Иногда эти потери совсем не оправданы. Представьте, что на страничке с кучей картинок и флэша есть мини-опрос «каким браузером вы пользуетесь?». После того, как пользователь проголосовал, страничка со всем тяжеловесным контентом полностью обновляется. Избежать подобной ситуации можно, если для отправки форм использовать ajax. Эта технология позволяет JavaScript отправлять абсолютно любые http-запросы, в том числе и точно такие же, какие летят на сервер при отправке формы. Прелесть состоит в том, что при выполнении подобного запроса страничка не перезагружается.

Для работы с ajax в используется JavaScript объект XMLHttpRequest.

1 Получение объекта XMLHttpRequest

В IE7 этот объект реализован только через ActiveX. Даже в 7 версии ActiveX все еще предпочтительнее из-за проблем с xml, поэтому вначале лучше пытаться получить его.

function getAjax(){
  var tran;
  //Для оперы, firefox'a, хрома
  if (window.XMLHttpRequest) {
    tran = new XMLHttpRequest();
  //Для ie
  } else if (window.ActiveXObject) {
    try {
      //Для новых версий
      tran = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      //Для cтарых
      tran = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return tran;
}

Существуют различные версии ActiveX объектов реализующих XMLHttpRequest и их «попробовать».

if (window.ActiveXObject) { // для IE до 7 версии
  var pref = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
  for(var i = 0; i < pref.length; i++)  {
    try  {
      return new ActiveXObject(pref[i] + ".XMLHTTP");
    } catch (e) {}
  }
}

2 Состояние запроса

Определяется значением свойства readyState:

  • 0 — запрос не инициализирован;
  • 1 — соединение открыто;
  • 2 — заголовок получен;
  • 3 — загрузка ответа;
  • 4 — ответ загружен.

Функция обработчик изменения состояния запроса задается как значение свойства onreadystatechange

var obj=getAjax();
obj.onreadystatechange=function(){
  if(obj.readyState==4)   {
  ... 
  }
}

Ответ сервера определяется значением свойства status, например:

  • 200 — все ок;
  • 404 — страница не найдена.

Данные, полученные от сервера, сохраняются в свойствах:

  • responseText — для текстовых данных;
  • responseXml — для xml данных.

3 Http заголовок

  • setRequestHeader(header, value) — позволяет установить значение полей http заголовка запроса, т.е. для отсылаемых данных. Заголовок должен устанавливаться после открытия соединения;
  • getResponseHeader(header) — позволяет получить значение полей http заголовка ответа, т.е. полученных данных;
  • getAllResponseHeaders() — получить http заголовок ответа полностью.

4 Открытие соединения и отправка запроса

Метод open открывает соединение, и имеет следующие аргументы:

  • mode — строка определяющая способ передачи («GET» или «POST»);
  • url — файл на сервере обрабатывающий данные;
  • b — true (асинхронный режим) / false (синхронный);
  • login — имя пользователя (не обязательный арг.);
  • password — пароль (не обязательный арг.).

Данные отправляются методом send. Если для отправки используется get, то аргумент метода устанавливают в null.

Для отправки GET-запроса будем использовать функцию sendGetRequest:

function sendGetRequest(tran, url, params, callback) {
  if(tran.readyState == 4 || tran.readyState == 0) {    
    tran.open('GET', url + '?' + urlEncodeData(params), true);
    tran.send('');
    if(callback) {
      tran.onreadystatechange = function () {
        if(tran.readyState == 4 && tran.status >= 200 && tran.status < 300)
          callback(tran.responseText);
      }
    }
  }
}

Эта функция, как вы видите, принимает три параметра url, params и callback. Тут params — это ассоциативный массив, содержащий параметры запроса. Он может выглядеть, например, вот так:

{login: 'admin', mail: 'admin@pro-prof.com'}

Последний необязательный параметр callback — это функция, которая будет вызвана, когда сервер ответит на запрос. В качестве параметра она принимает текст ответа. В теле функции sendGetRequest мы первым делом проверяем не занят ли объект tran передачей другого запроса. Свойство readyState содержит число, показывающее на какой стадии находится выполнение запроса. Когда оно равно 0, то запрос ещё не инициализирован, а когда 4, то он уже завершён. В строке

tran.open('GET', url + ‘?’ + urlEncodeData(params), true);

мы обращаемся к скрипту с адресом url и определяем тип запроса. Функция urlEncodeData преобразовывает параметры запроса из ассоциативного массива в строку. Её мы рассмотрим позже. Последний параметр функции open, в данном случае равный true, определяет будет выполнен асинхронный или синхронный запрос. В нашем случае запрос асинхронный. При синхронном запросе выполнение сценария приостанавливается до того момента, пока не будет получен ответ. При асинхронном запросе сценарий продолжает исполняться, в то время как выполняется запрос. В строчке

tran.send('');

отправляется сам запрос. Далее проверяется был ли передан при вызове функции параметр callback. Если, был, то присваиваем свойству onreadystatechange функцию, которая будет вызываться каждый раз, когда будет меняться свойство readyState. В теле этой функции будем вызывать функцию callback, но только если запрос завершён (readyState == 4) и при передаче не произошло никаких ошибок (tran.status >= 200 && tran.status < 300).

Функция для отправки POST-запроса аналогична:

function sendPostRequest(tran, url, params, callback) {
  if(tran.readyState == 4 || tran.readyState == 0) {
    tran.open('POST', url, true);
    tran.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    tran.send(urlEncodeData(params));
    if(callback) {
      tran.onreadystatechange = function () {
        if(tran.readyState == 4 && tran.status >= 200 && tran.status < 300)
          callback(tran.responseText);
      }
    }
  }        
}

Только здесь при отправке запроса параметры передаются не вместе с url, а в строчке

tran.send(urlEncodeData(params));

и заголовок запроса Content-Type (тип содержимого запроса), устанавливается равным application/x-www-form-urlencoded.

5 Пример использования метода get в ajax

Вводим текст в первом текстовом поле, а во втором отображается результат обработки этого текста серверным php скриптом test.php. Обработка заключается в преобразовании маленьких букв в большие. Это работает для английского языка и для некоторых русских символов. Так как в методе get протокола http аргументы передаются в строке адреса, то здесь использована функция encodeURI для преобразования русских букв в подходящий формат. Иначе при вводе русских букв получим знаки вопроса в квадратиках. С другими языками это может не пройти из-за различных настроек. Так на домашнем сервере (практически не настроенный) символы других языков не отображались, а на сервере хостинга отображаются. (пример делался в кодировке utf-8, что рекомендуется при работе с ajax вообще)

<script language="javascript" type="text/javascript">
   <!-- 
   var ajax=null;
   
   function getAjax(){
   if (window.ActiveXObject) // для IE
      return new ActiveXObject("Microsoft.XMLHTTP");
   else if (window.XMLHttpRequest) 
      return new XMLHttpRequest();
   else {
      alert("Browser does not support AJAX.");
      return null;
     }
   }
   
   function ajaxFunction(){
     ajax=getAjax();
     if (ajax != null) {
       ajax.open("GET", "test.php?in=" + encodeURI(document.getElementById("in").value), true);
     ajax.send(null);
     ajax.onreadystatechange = function(){
       if(ajax.readyState==4)  
         document.getElementById("out").value=ajax.responseText;  
       }
     }
   }
   -->
</script>
<form name="myform" action="" >
   Input text: <input type="text" onkeyup="ajaxFunction();"  name="in" id="in" />
   ajax result: <input type="text" name="out" id="out" />
</form>

Серверный файл выглядит так

<?php
if (isset($_GET['in'])) 
  echo strtoupper($_GET['in']); // для простоты пока так
?>

6 Пример использования метода post в ajax

Отличие от предыдущего примера в том, что здесь данные передаются на сервер методом post. Это удобнее, если данные имеют большой объем, так как длина строки адреса ограничена.

<script language="javascript" type="text/javascript">
   <!-- 
   var ajax=null;
   
   // без изменений
   function getAjax(){
   if (window.ActiveXObject) // для IE
      return new ActiveXObject("Microsoft.XMLHTTP");
   else if (window.XMLHttpRequest) 
      return new XMLHttpRequest();
   else {
      alert("Browser does not support AJAX.");
      return null;
     }
   }
   
   function ajaxFunction(){
   ajax=getAjax();
   var param;
   if (ajax != null) {   
      // метод POST, указываем просто имя файла
      ajax.open("POST","testpost.php",true);
      
      // если параметров несколько, то они разделяются &
      param="in="+document.getElementById('in').value;
   
      // добавляем стандартный заголовок http
      // посылаемый через ajax
      ajax.setRequestHeader("Content-type", 
            "application/x-www-form-urlencoded");
      
      // вроде эти могут тормозить      
      ajax.setRequestHeader("Content-length", param.length);
      ajax.setRequestHeader("Connection", "close"); 
      
      ajax.onreadystatechange = function(){      
      if(ajax.readyState==4 && ajax.status==200)  
            document.getElementById('out').value=ajax.responseText;  
      }
   
      // посылаем наши данные или пустую строку (param="")
      // главное не null
      ajax.send(param);  
   }
   }
   -->
</script>

<form name="myform">
   Input text: <input type="text" onkeyup="ajaxFunction();" name="in" id="in" />
   ajax result: <input type="text" name="out" id="out" />
</form>

Серверный файл выглядит так

<?php
  if (isset($_POST['in'])) 
    echo strtoupper($_POST['in']);
?>

7 Кэширование Ajax запросов

В IE get запросы кэшируются. Проблема решается установкой параметров заголовка на сервере, например, для php

// указываем, что документ устарел
header("Expires: Sat, 1 Jan 2000 00:00:00 GMT");  
// дата последнего обновления документа
header("Last-Modified: " . gmdate( "D, d M Y H:i:s") . " GMT"); 

//управление кэшем
header("Cache-Control: no-cache, must-revalidate"); 
header("Pragma: no-cache");

Либо заголовок устанавливается в JavaScript

ajax.setRequestHeader("Cache-Control", "no-store, no-cache, must-revalidate");
ajax.setRequestHeader("Cache-Control", "post-check=0, pre-check=0");
ajax.setRequestHeader("Pragma", "no-cache");

8 Кодировка в Ajax

Хотя кажется в методе setRequestHeader и можно установить кодировку, данные отсылаются в utf-8 (может особенности браузера). Поэтому, при работе с ajax рекомендуется работать с utf как при отсылке данных так и при получении.

По документации кодировка полученных данных определяется следующим образом. Если mime тип данных text/xml, application/xml, ...+xml,text/html, то кодировка определяется по стандарту этих документов.

Если кодировка не указана в заголовке в поле Content-type, то в полученных данных проверяется наличие одного из следующих байтовых префиксов:

  • 00 00 FE FF — utf32 be кодировка (be — старший байт в конце);
  • FF FE 00 00 — utf32 le кодировка (le — младший байт в конце);
  • FE FF — itf16 be кодировка;
  • FF FE — utf16 le кодировка;
  • EF BB BF — utf8 кодировка.

Если префикс не указан, то полагается кодировка utf8.

Когда возвращаемые данные генерируются скриптом, а не просто загружаются из файла, то заголовок необходимо указывать явно в начале скрипта. Например, в php это делается с помощью header

<?php header("Content-type: text/xml; charset=windows-1251");
// ниже генерим документ, например, xml
...

Если генерируемый документ не в utf, и при этом вы хотите использовать полученные данные, то необходима конвертация. В php это делается функцией iconv
iconv("utf-8","windows-1251",$_POST["data"]);

Если данные передаются методом get, необходимо использовать функцию encodeURI(url). В php скрипте с кодировкой utf, такие данные не требуют преобразований.

Код функции urlEncodeData, которая позволяет избежать некорректных запросов и помогает устранить проблемы с кодировкой, выглядит вот так:

function urlEncodeData(data) {  
  var arr = [];
  for(var p in data)
    arr.push(encodeURIComponent(p) + '=' + encodeURIComponent(data[p]));
  return arr.join('&');  
}

Эта функция лепит строку вида ‘par1=value1&par2=value2&..&parn=valuen’ из ассоциативного массива {par1: value1, par2: value2, …, parn: valuen}. При этом параметры и их значения обрабатываются функцией encodeURIComponent. Эта функция преобразовывает компоненту запроса к виду, безопасному для передачи на сервер. Она кодируют все символы escape-последовательностями в кодировке UTF-8, кроме букв латинского алфавита, десятичных цифр и !*()’. Например мы хотим передать на сервер следующее данные:

{par1: 'value1&value2', par2: 'value3'}

Тогда тело запроса будет выглядеть вот так: ‘par1=value1&value2&par2=value3’ и на сервере будет принято:

Array ( [par1] => value1, [value2] => '', [par2] => value3 );

Так же эта функция encodeURIComponent позволяет избежать проблем с кодировкой. Дело в том, ajax всегда передаёт текст в UTF-8 и, если этот текст не перекодировать в эту кодировку, то на сервере получим кучу «крокозябр».

9 Пример обработки xml и ajax

В данном примере серверный файл генерирует данные в формате xml, используя текст введенный в верхнем поле. После этого клиент разбирает результирующий xml объект, и вставляет значение элемента myitem во второе поле.

<script language="javascript" type="text/javascript">
   <!-- 
   var ajax=null;
   
   function getAjax(){
   if (window.ActiveXObject) // для IE
      return new ActiveXObject("Microsoft.XMLHTTP");
   else if (window.XMLHttpRequest) 
      return new XMLHttpRequest();
   else {
      alert("Browser does not support AJAX.");
      return null;
     }
   }
   
   function ajaxFunction2(){
   ajax=getAjax();
   var param;
   if (ajax != null) {   
   
   ajax.open("POST","testxml.php",true);
   
   // для FF 
   if (ajax.overrideMimeType)
      ajax.overrideMimeType("text/xml"); // или "text/xml" application/xml 
      
      // если параметров несколько то они разделяются &
      param="in="+document.getElementById("in").value;
      
      ajax.setRequestHeader("Content-Type",    
      "application/x-www-form-urlencoded; charset=UTF-8"); 
          
      ajax.onreadystatechange = function(){       
      var xml;
      if(ajax.readyState==4 && ajax.status==200){  
      
           // Исправление ошибки в IE для ActveX  
   		if(!ajax.responseXML.documentElement && ajax.responseStream)			
   			 ajax.responseXML.load(ajax.responseStream);
   		
           xml=ajax.responseXML;                  
    
           document.getElementById("out").value=
           xml.getElementsByTagName("myitem")[0].firstChild.nodeValue ;
          }  
      } 
      ajax.send(param);  
   }
   }
   -->
</script>

Серверный файл выглядит следующим образом:

<?php
  echo <<<EOD
  <?xml version="1.0" encoding="utf-8" ?>
  <myitem>
    Hello World,
    {$_POST['in']}
    привет мир
  EOD;

  if (isset($_POST['in'])) 
     echo $_POST['in'];  
  echo " </myitem>" ;  
?>

Если будет допущена ошибка в xml, например, пропущен закрывающий тег, то xml объект не будет создан.

10 Пример Ajax приложение с jquery

Библиотека JQuery поддерживает несколько методов для работы с ajax: get, post и ajax. Последний метод позволяет указать явно различные настройки для загрузки страницы.

Ниже приведены предыдущие примеры переписанные с использованием JQuery.

Demo get metod:

<form name="myform">
Demo get metod<br>
Input text: <input type="text" onkeyup="ajaxFunction();" 
                name="in" id="in" />
ajax result: <input type="text" name="out" id="out" />
</form>

<script language="javascript" type="text/javascript">
<!-- 
function ajaxFunction(){
  $.get("test.php", { "in" : $("#in").val()},
  function(data){
     $("#out").val(data);
  
  }, "text");
}
-->
</script>

Demo post metod:

<form>
Demo post metod<br>
Input text: <input type="text" onkeyup="ajaxFunction1();" 
                name="in1" id="in1" />
ajax result: <input type="text" name="out1" id="out1" />
</form>

<script language="javascript" type="text/javascript">
<!-- 
function ajaxFunction1(){
  $.post("testpost.php", { "in" : $("#in1").val()},
  function(data){
     $("#out1").val(data); 
  }, "text");
}
-->
</script>

Demo ajax XML metod:

<form name="form2">
Demo ajax method <br>
Input text: <input type="text" onkeyup="ajaxFunction2();" 
             name="in2" id="in2" />
<br>
ajax result: <textarea rows=5 cols=40 name="out2" 
              id="out2" value=""></textarea> 
</form>

<script language="javascript" type="text/javascript">
<!-- 
// создание XML объекта по строке
function doXML(data){
var xml;
if(window.ActiveXObject){ // IE
  xml = new ActiveXObject("Microsoft.XMLDOM");
  xml.async = false;
  xml.loadXML(data);
  }
else { 
   if (document.implementation.createDocument){ // FF и Opera
      var parser=new DOMParser();    
      xml = parser.parseFromString(data, "text/xml");
      } 
  }   
return xml;
}

function ajaxFunction2(){
$.ajax({
  url: "testxml.php",
  cache: false,
  type: "POST",
  data: "in="+$("#in2").val(),
  dataType: "text", // тип xml не сработал 
  success: function(data){
  var xml=doXML(data);  
  $("#out2").val( $(xml).find('myitem').text());    
  }
});  
}
-->
</script>

1. Во многих примерах к методам get и post объект указывается без кавычек

{in : $("#in").val()}

Это работает только в FF. Если имя объекта закавычить, то работает и в FF и в IE

{"in" : $("#in").val()}

2. На всякий случай, вдруг кто запутается. Для всех трех примеров я использовал серверные файлы от предыдущих примеров, которые работают только с одной переменной in. Отсюда некоторое не соответствие имен в

"in" : $("#in1").val()

11 Ajax и innerHTML

Суть проблемы в том, что после изменения средствами аякса innerHTML некоторого элемента, использовать это новое значение в блоке скрипта можно со второй попытки. Пусть есть следующий код

<script type="text/javascript">
   function af(iid){
     var ajax=getAjax();
     if (ajax != null) {      
      ajax.open("POST","anytext.php",true);
      ajax.setRequestHeader("Content-type", 
            "application/x-www-form-urlencoded");
      ajax.onreadystatechange = function() {      
        if(ajax.readyState==4 && ajax.status==200)  
            document.getElementById(iid).innerHTML=ajax.responseText;  
            // здесь alert(document.getElementById(iid).innerHTML);
            // тоже будет работать корректно
            
      }
      ajax.send("");  
     }
   }
   
   function test(){
     af('test');
     // в первый раз выйдет пустая строка
     alert(document.getElementById('test').innerHTML);
     // со второго раза ок
     alert(document.getElementById('test').innerHTML);
   }
</script>

21 апреля 2007 года

В пользе RSS уже давно никто не сомневается. Я позволю себе сказать пару слов о том, как правильно сделать RSS-канал на вашем сайте. В заметке я буду использовать вымышленные примеры для экспорта информации о новых статьях, хотя, разумеется, через RSS можно экспортировать вообще всё, что угодно: новости, прогноз погоды, курсы валют, записи в блоге. В случае появления дополнительных вопросов вы всегда сможете просмотреть рабочие варианты RSS моего сайта и блога.

Фактически формат RSS представляет
собой веб-страницу, сформированную с применением определенных правил, которая
содержит информацию о нескольких элементах, такую как заголовок, описание, ссылку, дату и
т. д., и эту страницу можно создать обычными средствами. Например, сделать
XML-файл примерно такого содержания:

<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0">
   <channel>
      <title>Название RSS-потока</title>
      <link>http://site.ru</link>
      <description>Описание RSS-потока</description>
      <item>
         <title>Название 1</title>
         <link>http://site.ru/articles/1</link>
         <description>Описание статьи 1</description>
         <author>Автор &lt;author@site.ru&gt;</author>
         <pubDate>Sun, 25 Mar 2007 00:00:00 +0300</pubDate>
      </item>
      <item>
         <title>Название 2</title>
         <link>http://site.ru/articles/2</link>
         <description>Описание статьи 2</description>
         <author>Автор &lt;author@site.ru&gt;</author>
         <pubDate>Sun, 18 Mar 2007 00:00:00 +0300</pubDate>
      </item>
      <item>
         <title>Название 3</title>
         <link>http://site.ru/articles/3</link>
         <description>Описание статьи 3</description>
         <author>Автор &lt;author@site.ru&gt;</author>
         <pubDate>Sun, 11 Mar 2007 00:00:00 +0300</pubDate>
      </item>
   </channel>
</rss>

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

Понятно, что если на сайте есть хотя бы минимальная автоматизация, RSS может генерироваться скриптом, например, на PHP. Можно предложить два разумных способа работы этого скрипта:

  1. Скрипт вызывается при обновлении сайта и результаты своей работы сохраняет в обычный XML-файл, на который вы будете давать ссылки.
  2. Скрипт отрабатывает каждый раз, когда браузер (или иной пользовательский агент) обращается к RSS и отдает результаты браузеру.

Здесь нужно остановиться и обратить внимание на основные факты: зачем вы делаете RSS, большая ли аудитория у сайта и т. д. Различия между первым и вторым способом в основном связаны с особенностями работы протокола HTTP, а именно, с заголовками Last-Modified и If-Modified-Since (ознакомьтесь с описанием работы этих заголовков, повторяться смысла нет, а дальше они активно используются). Различия между этими двумя способами мы посмотрим на примере первого и повторных обращений к RSS-ленте, а потом я приведу одну из возможных реализаций.

Статический XML-файл

При первом обращении содержимое этого файла отдается целиком. При повторных обращениях (когда кто-то подписан на ваш RSS) благодаря механизму If-Modified-Since сервер сообщает, что файл не изменился. В случае обновления файла с RSS он опять отдается полностью.

Динамический скрипт

При первом обращении он отдает информацию обо всех элементах. При повторных обращениях скрипт сообщает, что изменений не было, и ничего не отправляет. Однако если мы добавили, например, еще одну статью, то по содержимому заголовка If-Modified-Since скрипт определяет, когда было последнее обращение к RSS, и выдает только добавившиеся элементы (идея найдена на xpoint.ru). Именно здесь заключается то улучшение, которого можно добиться вторым способом.

Можно найти еще одно преимущество: если мы что-нибудь изменили на сайте, то RSS нужно сгенерировать заново. Что произойдет дальше, существенно зависит от программы, читающей RSS. Но в любом случае, если мы написали что-то ошибочное, эта ошибка попала в RSS и кто-то это уже прочел, исправить ситуацию мы не в состоянии. Максимум, что можно сделать, это отправлять новым пользователям исправленную версию. Именно так и поступит наш скрипт.

Описание скрипта

Есть смысл через RSS отправлять
информацию о нескольких последних статьях (обычно так и делают). Чем чаще в
RSS появляются новые элементы, тем больше информации нужно
экспортировать при постоянной частоте обращения, чтобы подписанные пользователи
не пропустили каких-нибудь объявлений.

В скрипте предполагается, что функция get_recent() возвращает массив с
описанием статей, причем количество элементов будет задаваться размером
массива. Её придется писать вам самим. Это просто, нужно всего лишь при
переиндексации (если сайт использует файлы) записать в определенный файл
информацию о последних статьях, и считывать ее в вышеупомянутой функции. Или
обращаться к базе данных и выбирать информацию о последних статьях.

Функция get_last_modified() должна возвращать дату и время последней
новости, экспортируемой через RSS, и это значение будет установлено в заголовке
Last-Modified. Хотя здесь можно отдавать время внесения последних изменений
в новости, экспортируемые через RSS в надежде на то, что программы для чтения RSS
обновят ранее полученную информацию.

Следует отметить, что в некоторых полях отдаваемого XML, например, в поле description
могут присутствовать html-теги, но они должны быть преобразованы в entities (знак < в
комбинацию &lt; и т. д.), что делает функция PHP htmlspecialchars().

Итак, сам скрипт:

<?

// Запрет кеширования, см. описание
function no_cache() {
   header("Expires: Mon, 26 Jul 1997 00:00:00 GMT");
   header("Pragma: no-cache");
}

// Перевод даты из формата RFC 2822 в unixstamp
function date2unixstamp($s) {
   $months = array (
      "Jan"=>1, "Feb"=>2, "Mar"=>3,
      "Apr"=>4, "May"=>5, "Jun"=>6,
      "Jul"=>7, "Aug"=>8, "Sep"=>9,
      "Oct"=>10, "Nov"=>11, "Dec"=>12);

   $a = explode(" ", $s);
   $b = explode(":", $a[4]);
   return gmmktime($b[0], $b[1], $b[2],
      $months[$a[2]], $a[1], $a[3]);
}

// Получение массива элементов
function get_recent() {
   ...
}

// Дата и время последнего изменения
function get_last_modified() {
   ...
}

$HTTP_HOST = isset($_SERVER["HTTP_HOST"]) ?
   $_SERVER["HTTP_HOST"] : "site.ru"; // ваш сайт

no_cache();

$recent_articles = get_recent();

// Буферизация для установки заголовка Content-Length
// и сжатия отправляемых данных
ob_start();
ob_start("ob_gzhandler");

echo '<?xml version="1.0" encoding="windows-1251"?>'."n";
?><rss version="2.0">
   <channel>
      <title>Название RSS</title>
      <link><?=$HTTP_HOST?></link>
      <description>Описание</description>
<?

$last_date = 0;

if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
   $last_date = date2unixstamp($_SERVER["HTTP_IF_MODIFIED_SINCE"]);
}

$counter = 0;

foreach($recent_articles as $recent) {
   if ($recent["date"] > $last_date) {
      $counter++;
?>
      <item>
         <title>
            <?=htmlspecialchars($recent["title"])?>
         </title>
         <link><?=$recent["link"]?></link>
         <description>
            <?=htmlspecialchars($recent["desc"])?>
         </description>
         <author>Автор &lt;author@site.ru&gt;</author>
         <guid><?=$recent["link"]?></guid>
         <pubDate><?=date("r", $recent["date"])?></pubDate>
      </item>
<?
   }
}
?>
   </channel>
</rss>
<?

if (!$counter) {
   header("HTTP/1.1 304 Not Modified");
   exit();
}

ob_end_flush();

header("Content-Length: ".ob_get_length());
header("Last-Modified: ".
   gmdate("D, d M Y H:i:s", get_last_modified())." GMT");
header("Content-Type: text/xml; charset=WINDOWS-1251");
ob_end_flush();

?>

Чтобы скрипт заработал, достаточно на него дать ссылку. Если вы хотите,
чтобы у него было «красивое» имя вроде http://site.ru/rss.xml,
пропишите в файл .htaccess следующее:

RewriteEngine on
Options +FollowSymlinks
RewriteBase /

RewriteRule ^rss.xml$ some_path/php123/rss.php [L]

some_path/php123/rss.php — это «некрасивый» путь, по которому
лежит наш скрипт. Если mod_rewrite не установлен, тогда пропишите туда же вот что:

AddType application/x-httpd-php xml

и поместите скрипт прямо в файл rss.xml. Будьте внимательны!
В последнем случае все файлы с расширением xml будут обрабатываться
парсером PHP.

Чтобы браузеры смогли определить, что на вашем сайте есть RSS, в разделе описаний
страницы следует разместить тег <link>:

<html>
<head>
   <meta http-equiv="Content-Type"
      content="text/html; charset=windows-1251" />
   <title>Заголовок страницы</title>
   <link rel="alternate" type="application/rss+xml"
      title="Название RSS" href="http://site.ru/rss.xml" />
</head>
<body>
   ...
</body>
</html>

На этом всё. Пользуйтесь на здоровье.

От:

Hazg

 
Дата:  07.02.07 10:32
Оценка:

Я честно поискал на форуме, в гугле и теперь пришел к вам. Что есть:
сайт php, отдает страницы в win кодировке. Так же есть часть сайта, на так называемом ajax’е. У меня на машине под всеми браузерами (кроме konqueror в виртуальном linux) все ок, а у нескольких пользователей с ie6 русским походу хромает кодировка того что сайт накачивает через ajax («MSXML2.XMLHttp.5.0″,»MSXML2.XMLHttp.4.0″,»MSXML2.XMLHttp.3.0″,»MSXML2.XMLHttp»,»Microsoft.XMLHttp», XMLHttpRequest). Видимо, надо проставить где то кодировку. Как?
так пробовал: httprequest.setRequestHeader(‘Content-Type: text/xml; charset=windows-1251’);

От:

Mamut

Швеция

http://dmitriid.com
Дата:  07.02.07 13:11
Оценка:

H>Я честно поискал на форуме, в гугле и теперь пришел к вам. Что есть:
H>сайт php, отдает страницы в win кодировке. Так же есть часть сайта, на так называемом ajax’е. У меня на машине под всеми браузерами (кроме konqueror в виртуальном linux) все ок, а у нескольких пользователей с ie6 русским походу хромает кодировка того что сайт накачивает через ajax («MSXML2.XMLHttp.5.0″,»MSXML2.XMLHttp.4.0″,»MSXML2.XMLHttp.3.0″,»MSXML2.XMLHttp»,»Microsoft.XMLHttp», XMLHttpRequest). Видимо, надо проставить где то кодировку. Как?
H>так пробовал: httprequest.setRequestHeader(‘Content-Type: text/xml; charset=windows-1251’);

Сам PHP должен еще выдавать что-то типа:

<?php 
    header('Content-type: text/xml; charset=win-1251');
?>

А вообще лучше отдавать все в Юникоде

От:

ddocker

Россия

www.codelab.ru
Дата:  07.02.07 13:43
Оценка:

M>Сам PHP должен еще выдавать что-то типа:
M>

M><?php 
M>    header('Content-type: text/xml; charset=win-1251');
M>?>
M>



M>А вообще лучше отдавать все в Юникоде

кстати а в 2-х словах как там у разных браузеров с кодировкой при ajax-е: ie плохо(глючно или вообще нет) поддерживает все кроме utf-8, а лиса и опера нормально с другими кодировками работают?

… << RSDN@Home 1.1.4 stable SR1 rev. 568>>

От:

Hazg

 
Дата:  07.02.07 15:43
Оценка:

M>

M><?php 
M>    header('Content-type: text/xml; charset=win-1251');
M>?>
M>


есть. естессно есть. сам пишу и вижу, что ошибаюсь. text/xml; Будем пробовать Все спасибо после.

M>А вообще лучше отдавать все в Юникоде

Хм. Как я понимаю, в отдавая в юникоде мы получаем почти в два раза больше траффика??? А зачем тогда вообще ajax нужен? Из-за моды? Нет уж. Сайт кроме русского других языков знать не должен, значит юникод и не нужен.

От:

.

Великобритания

 
Дата:  07.02.07 16:40
Оценка:

Hazg wrote:

> больше траффика??? А зачем тогда вообще ajax нужен? Из-за моды? Нет уж.

> Сайт кроме русского других языков знать не должен, значит юникод и не нужен.
По правилам русского языка кавычки должны быть «такими», а длинное тире — такое, а не «-» такое.
Конечно, всё это в однобайтовые кодировки не входит… только юникод.

А то что трафик больше — установите gzip.

Posted via RSDN NNTP Server 2.0

но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай

От:

Mamut

Швеция

http://dmitriid.com
Дата:  08.02.07 08:00
Оценка:

M>>А вообще лучше отдавать все в Юникоде
D>кстати а в 2-х словах как там у разных браузеров с кодировкой при ajax-е: ie плохо(глючно или вообще нет) поддерживает все кроме utf-8, а лиса и опера нормально с другими кодировками работают?

У меня недавно ИЕ не поддержал меня с utf-8 Правда, это могут быть проблемы jQuery, которой я пользуюсь, а простого способа проверить это под ИЕ нет

Так что не знаю

От:

Hazg

 
Дата:  08.02.07 08:47
Оценка:

9 (1)

Сам написал, сам отвечаю Значица, вместо суммари:
Объекту XmlRequest (и ms и остальным) нужны не только заголовки в запросе, но и валидный код (валидный соответственно заголовкам.) Не знаю как для вас, но для меня это было открытие. нет, с xml все понятно, данные, структура… Но требовать валидного html? Требует. Проблема с кодировками решилась очень просто:
Запрашиваемый документ должен отдаваться в виде (если запрашивается text/html, естессно.):

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
</head>
<body>текст в виндовой кодировке</body>
</html>

Спорить с этим сложно, так как после вышеперечисленного страницы нормально показываются в win кодировке в opera, ff, ie, linux ff, konqueror, и даже safari webkit. Забираеться в win и показывается в win.

P.S. Я с ajax’ом знаком первую неделю, и возможно сделал открытие велосипеда. Но почему все настаивают на unicode, который, похоже, просто выдается корректно, как бы не был некорректен ответ на запрос?

От:

PGG

Россия

http://pavel.gorlov.name
Дата:  13.05.07 11:47
Оценка:

Добрый день! А уменя другая беда. Я работаю с DOJO Ajax’ом, и при аякс-посте текст из форм мой win1251 страницы конвертится в карявы типа това, Я перерыл всё, я незнаю как побороть этот баг. Страница win1251, на сервере .php тоже 1251, а от страницы уходит това…… Что делать, как быть?

От:

PGG

Россия

http://pavel.gorlov.name
Дата:  13.05.07 11:59
Оценка:

Подробнее, пишу в input формы к примеру «Текст», dojo перед постом конвертит в

& #1090;& #1086;& #1074;& #1072;& #1090;& #1086; & #1074;& #1072;

незнаю как отключить или как в php из этого сделать нормальный 1251

p.s. пробел между & и # я поставил специально для того что бы текст не преобразовывался в обычный…

От:

Hazg

 
Дата:  13.05.07 20:12
Оценка:
От:

Mamut

Швеция

http://dmitriid.com
Дата:  14.05.07 07:03
Оценка:

Здравствуйте, Hazg, Вы писали:

H>Сам написал, сам отвечаю Значица, вместо суммари:

H>Объекту XmlRequest (и ms и остальным) нужны не только заголовки в запросе, но и валидный код (валидный соответственно заголовкам.) Не знаю как для вас, но для меня это было открытие. нет, с xml все понятно, данные, структура… Но требовать валидного html? Требует.

Кстати. Есть еще одна фишка с валидным ХТМЛем. Если пришедший ответ с сервера будет вставляться в документ, то для IE в таблицах обязательно надо ставить <tbody> Я на это нарвался здесь

От:

PGG

Россия

http://pavel.gorlov.name
Дата:  14.05.07 07:05
Оценка:

H>Лежит на php.net в примерах. Чесно говоря сейчас я не особо в контексте ) так что, если глупость сморозил извиняй. (it’s work). Че касается твоей библиотечки…. Фиг знает. Не пользовался.
H>P.S. Что за товатова такая? Э так ее хотел увидеть в нормальном декодированном виде )))
H>Если вопросы остались, пиши

Спасибо! Это то, что нужно, хотя правда интересно почему такая ерудна происходит перед отправкой.
А «това» это и есть карявки, которые RSDN преобразовал в нормальный вид.

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Здесь Вы найдете полное описание объекта XMLHTTPRequest, способы использования, форматы данных и разбор частых проблем.

Полезного чтения.

Объект XMLHttpRequest

Объект XMLHttpRequest (или, сокращенно, XHR) дает возможность браузеру делать HTTP-запросы к серверу без перезагрузки страницы.

Несмотря на слово XML в названии, XMLHttpRequest может работать с данными в любом текстовом формате, и даже c бинарными данными. Использовать его очень просто.

Кроссбраузерное создание объекта запроса

В зависимости от браузера, код для создания объекта может быть разный.
Кроссбраузерная функция создания XMLHttpRequest:

function getXmlHttp(){
  var xmlhttp;
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

Функция тупо перебирает возможные внутренние реализации и возвращает начальный объект XMLHttpRequest. Существует и масса других рабочих кроссбраузерных функций, однако все они по сути делают то же самое.

Использование XMLHTTPRequest

Различают два использования XmlHttpRequest. Первое — самое простое, синхронное.

Синхронный XMLHttpRequest

В этом примере через XMLHTTPRequest с сервера запрашивается страница http://example.org/, и текст ответа сервера показывается через alert().

var xmlhttp = getXmlHttp()
xmlhttp.open('GET', '/xhr/test.html', false);
xmlhttp.send(null);
if(xmlhttp.status == 200) {
  alert(xmlhttp.responseText);
}

Здесь сначала создается запрос, задается открытие (open) синхронного соединение с адресом /xhr/test.html и запрос отсылается с null,
т.е без данных.

При синхронном запросе браузер «подвисает» и ждет на строчке 3, пока сервер не ответит на запрос. Когда ответ получен — выполняется строка 4, код ответа сравнивается с 200 (ОК), и при помощи alert
печатается текст ответа сервера. Все максимально просто.

Свойство responseText получит такой же текст страницы, как браузер, если бы Вы в перешли на /xhr/test.html. Для сервера
GET-запрос через XmlHttpRequest ничем не отличается от обычного перехода на страницу.

Асинхронный XMLHttpRequest

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

var xmlhttp = getXmlHttp()
xmlhttp.open('GET', '/xhr/test.html', true);
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4) {
     if(xmlhttp.status == 200) {
       alert(xmlhttp.responseText);
         }
  }
};
xmlhttp.send(null);

Асинхронность включается третьим параметром функции open. В отличие от синхронного запроса, функция send() не останавливает
выполнение скрипта, а просто отправляет запрос.

Запрос xmlhttp регулярно отчитывается о своем состоянии через вызов функции xmlhttp.onreadystatechange. Состояние под номером 4 означает конец выполнения, поэтому функция-обработчик
при каждом вызове проверяет — не настало ли это состояние.

Вообще, список состояний readyState такой:

  • 0 — Unitialized
  • 1 — Loading
  • 2 — Loaded
  • 3 — Interactive
  • 4 — Complete

Состояния 0-2 вообще не используются.

Вызов функции с состоянием Interactive в теории должен происходить каждый раз при получении очередной порции данных от сервера.
Это могло бы быть удобным для обработки ответа по частям, но Internet Explorer не дает доступа к уже полученной части ответа.

Firefox дает такой доступ, но для обработки запроса по частям состояние Interactive все равно неудобно из-за сложностей обнаружения ошибок соединения.
Поэтому Interactive тоже не используется.

На практике используется только последнее, Complete.

Если хотите углубиться в тонкости багов браузеров c readyState, отличными от 4, то многие из них рассмотрены в статье на
Quirksmode (англ.).

Не используйте синхронные запросы

Синхронные запросы применяются только в крайнем случае, когда кровь из носу необходимо дождаться ответа сервера до продолжения скрипта. В 999 случаях из 1000
можно использовать асинхронные запросы. При этом общий алгоритм такой:

  1. Делаем асинхронный запрос
  2. Рисуем анимированную картинку или просто запись типа «Loading…»
  3. В onreadystatechange при достижении состояния 4 убираем Loading и, в зависимости от status вызываем обработку ответа или ошибки.

Кроме того, иногда полезно ставить ограничение на время запроса. Например, хочется генерировать ошибку, если запрос висит более 10 секунд.

Для этого сразу после send() через setTimeout ставится вызов обработчика ошибки, который очищается при получении ответа и обрывает запрос с генерацией ошибки,
если истекли 10 секунд.

Таймаут на синхронный запрос ставить нельзя, браузер может висеть долго-долго.. А вот на асинхронный — пожалуйста.

Этот пример демонстрирует такой таймаут.

var xmlhttp = getXmlHttp()
xmlhttp.open("POST", "/someurl", true);
xmlhttp.onreadystatechange=function(){
  if (xmlhttp.readyState != 4) return
  clearTimeout(timeout) // очистить таймаут при наступлении readyState 4
  if (xmlhttp.status == 200) {
      // Все ок
      ...
      alert(xmlhttp.responseText);
      ...
  } else {
      handleError(xmlhttp.statusText) // вызвать обработчик ошибки с текстом ответа
  }
}
xmlhttp.send("a=5&b=4");
// Таймаут 10 секунд
var timeout = setTimeout( function(){ xmlhttp.abort(); handleError("Time over") }, 10000);
function handleError(message) {
  // обработчик ошибки
  ...
  alert("Ошибка: "+message)
  ...
}

Методы объекта XMLHttpRequest

open()

Варианты вызова:

  • open( method, URL )
  • open( method, URL, async )
  • open( method, URL, async, userName )
  • open( method, URL, async, userName, password )

Первый параметр method — HTTP-метод. Как правило, используется GET либо POST, хотя доступны и более экзотические, вроде TRACE/DELETE/PUT и т.п.

URL — адрес запроса. Можно использовать не только HTTP/HTTPS, но и другие протоколы, например FTP и FILE://. При этом есть ограничения безопасности, так называемая
«same origin policy»: запрос со страницы можно отправлять только на тот домен и порт, с которого она пришла.

Ниже это ограничение и способы обхода будут рассмотрены подробнее.

async = true задает асинхронные запросы, эта тема была поднята выше.

userName, password — данные для HTTP-авторизации.

send()

Отсылает запрос. Аргумент — тело запроса. Например, GET-запроса тела нет, поэтому используется send(null), а для POST-запросов тело содержит параметры запроса.

abort()

Вызов этого метода xmlhttp.abort() обрывает текущий запрос.

Здесь есть одно НО для браузера Internet Explorer. Успешный вызов abort() на самом деле может не обрывать соединение,
а оставлять его в подвешенном состоянии на некоторый таймаут (20-30 секунд). Отловить такие повисшие соединения можно через прокси для отладки, например, Fiddler.

У браузера есть лимит: не более 2 одновременных соединений с одним доменом-портом. Т.е, если два соединения уже висят (и отвиснут по таймауту), то третье открыто не
будет, пока одно из них не умрет. Надеюсь, Вы с такой проблемой не столкнетесь. Ее можно обойти использованием кросс-доменных XmlHttpRequest.

Устанавливает заголовок name запроса со значением value. Если заголовок с таким name уже есть — он заменяется.

Например,

xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Возвращает строку со всеми HTTP-заголовками ответа сервера.

Возвращает значение заголовка ответа сервера с именем headerName.

Свойства объекта XMLHttpRequest

onreadystatechange

Ссылается на функцию-обработчик состояний запроса. В некоторых браузерах функция имеет аргумент — событие. Не используйте его, он совершенно лишний.

readyState

Номер состояния запроса от 0 до 4. Используйте только 4 («completed»).

responseText

Текст ответа сервера. Полный текст есть только при readyState=4, ряд браузеров дают доступ к полученной части ответа сервера при readyState=3.

responseXML

Ответ сервера в виде XML, при readyState=4.

Это свойство хранит объект типа XML document, с которым можно обращаться так же, как с обычным document. Например,

var authorElem = xmlhttp.responseXML.getElementById('author');

Чтобы браузер распарсил ответ сервера в свойство responseXML, в ответе должен быть заголовок Content-Type: text/xml.

Иначе свойство responseXML будет равно null.

status

Для HTTP-запросов — статусный код ответа сервера: 200 — OK, 404 — Not Found, и т.п. Браузер Internet Explorer может также присвоить status код ошибки WinInet,
например 12029 для ошибки «cannot connect».

Запросы по протоколам FTP, FILE:// не возвращают статуса, поэтому нормальным для них является status=0.

statusText

Текстовая расшифровка status, например «Not Found» или «OK».

GET и POST-запросы. Кодировка.

Во время обычного submit’а формы браузер сам кодирует значения полей и составляет тело GET/POST-запроса для посылки на сервер. При работе через XmlHttpRequest, это нужно делать самим, в javascript-коде. Большинство проблем и вопросов здесь связано с непониманием, где и какое кодирование нужно осуществлять.

Вначале рассмотрим общее кодирование запросов, ниже — правильную работу с русским языком для windows-1251.

Существуют два вида кодирования HTTP-запроса. Основной — urlencoded, он же — стандартное кодирование URL. Пробел представляется как %20, русские буквы и большинство спецсимволов кодируются, английские буквы и дефис оставляются как есть.

Способ, которым следует кодировать данные формы при submit’е, задается в ее HTML-таге:

<form method="get"> // метод GET с кодировкой по умолчанию
<form method="post" enctype="application/x-www-form-urlencoded"> // enctype явно задает кодировку
<form method="post"> // метод POST с кодировкой по умолчанию (urlencoded, как и предыдущая форма)

Если форма submit’ится обычным образом, то браузер сам кодирует (urlencode) название и значение каждого поля данных (input и т.п.) и отсылает форму на сервер в закодированном виде.

Формируя XmlHttpRequest, мы должны формировать запрос «руками», кодируя поля функцией encodeURIComponent.

Конечно, пропускать через encodeURIComponent стоит только те переменные, в которых могут быть спецсимволы или не английские буквы, т.е которые и будут как раз закодированы.

Например, для посылки GET-запроса с произвольными параметрами name и surname, их необходимо закодировать вот так:

// Пример с GET
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("GET", '/script.html?'+params, true)
...
xmlhttp.send(null)

В методе POST параметры передаются не в URL, а в теле, посылаемом через send(). Поэтому params нужно указывать не в адресе, а при вызове send()

Кроме того, при POST обязателен заголовок Content-Type, содержащий кодировку. Это указание для сервера — как обрабатывать (раскодировать) пришедший запрос.

// Пример с POST
...
var params = 'name=' + encodeURIComponent(name) + '&surname=' + encodeURIComponent(surname)
xmlhttp.open("POST", '/script.html', true)
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
...
xmlhttp.send(params)

Заголовки Content-Length, Connection в POST-запросах, хотя их и содержат некоторые «руководства», обычно не нужны. Используйте их, только если Вы действительно знаете, что делаете.

Запросы multipart/form-data

Второй способ кодирования — это отсутствие кодирования. Например, кодировать не нужно для пересылки файлов. Он указывается в форме (только для POST) так:

<form method="post" enctype="multipart/form-data">

В этом случае при отправке данных на сервер ничего не кодируется. А сервер, со своей стороны, посмотрев на Content-Type(=multipart/form-data), поймет, что пришло.

Возможности XmlHttpRequest позволяют создать запрос с любым телом. Например, можно вручную сделать POST-запрос, загружающий на сервер файл. Функционал создания
таких запросов есть, в частности, во фреймворке dojo. Но можно реализовать его и самому, прочитав о нужном формате тела POST и заголовках.

Кодировка (языковая)

Если Вы используете только UTF-8 — пропустите эту секцию.

Все идущие на сервер параметры GET/POST, кроме случая multipart/form-data, кодируются в UTF-8. Не в кодировке страницы, а именно в UTF-8. Поэтому, например, в PHP их нужно при необходимости перекодировать функцией iconv.

<?php
// ajax.php
$name = iconv('UTF8','CP1251',$_GET['name']);
?>

С другой стороны, ответ с сервера браузер воспринимает именно в той кодировке, которая указана в заголовке ответа Content-Type. Т.е, опять же, в PHP, чтобы браузер воспринял ответ в windows-1251 и нормально отобразил данные на странице в windows-1251,
нужно послать заголовок с кодировкой в php-коде, например так:

<?php
// ajax.php
header('Content-Type: text/plain; charset=windows-1251');
?>

Или же, такой заголовок должен добавить сервер. Например, в apache автоматически добавляется кодировка опцией:

# в конфиге апача
AddDefaultCharset windows-1251

Частые проблемы

Кеширование

Многие браузеры поддерживают кеширование ответов на XmlHttpRequest запросы. При этом реализации кеширования немного разные.

Например, при повторном XmlHttpRequest на тот же URL, Firefox посылает запрос с заголовком «If-Modified-Since» со значением,
указанным в заголовке «Last-Modified» предыдущего ответа.

А Internet Explorer делает так, только когда кешированный ответ устарел, т.е после времени из заголовка «Expires» предыдущего ответа. Поэтому, кстати, многие думают,
что Internet Explorer вообще не очищает кеш ответов.

Самое простое решение проблемы — просто убрать кеширование. Например, при помощи заголовков, или добавлением случайного параметра в URL типа:

xmlhttp.open("GET", "/service.php?r="+Math.random(), true)

Есть, однако, ряд случаев, когда кеширование XMLHttpRequest браузером полезно, улучшает время ответа и экономит трафик, просто нужно уметь его использовать.

Пример демонстрирует универсальный код работы с кешем для Internet Explorer и Firefox. Этот пример обеспечивает посылку «If-Modified-Sinse»-заголовка IE при обращениях к закешированному запросу.

var xmlhttp = getXmlHttp()
xmlhttp.open("GET", uri, false); // синхронный запрос для примера
xmlhttp.send(null);
if(!xmlhttp.getResponseHeader("Date")) {  // 1
  var cached = xmlhttp;
  xmlhttp = getXmlHttp()
  var ifModifiedSince = cached.getResponseHeader("Last-Modified");
  ifModifiedSince = (ifModifiedSince) ? ifModifiedSince : new Date(0); // January 1, 1970
  xmlhttp.open("GET", uri, false);
  xmlhttp.setRequestHeader("If-Modified-Since", ifModifiedSince);
  xmlhttp.send(null);
  if(xmlhttp.status == 304)  {
    xmlhttp = cached;
  }
}

Разбор примера работы с кешем

Внешний тест (1) опирается на то, что в Internet Explorer, если запрос возвращается из кеша без перепроверки, заголовок Date — пустая строка. Поэтому при этом нужно сделать дополнительный запрос, который как раз и будет реальным запросом к серверу.

Когда делаем дополнительный запрос, что ссылку на кешированый запрос сохраняем, т.к если код ответа дополнительного запроса — «304 Not Modified», то его тело будет пустой строкой, и нужно будет вернуться к кешированному объекту.

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

Пример выше опирается на то, что сервер всегда выдает заголовок «Date», что верно для большинства конфигураций.
В нем делается синхронный запрос. В асинхронном случае, проверку на Date и т.д нужно делать после получения ответа в функции-обработчике onreadystate.

Повторное использование объекта XmlHttpRequest

В Internet Explorer, если open() вызван после установки onreadystatechange, может быть проблема с повторным использованием этого XmlHttpRequest.

Чтобы использовать заново XmlHttpRequest, сначала вызывайте метод open(), а затем — присваивайте onreadystatechange. Это нужно из-за того, что IE самостоятельно очищает
объект XmlHttpRequest в методе open(), если его статус «completed».

Вызывать abort() для перенаправления запроса на другой URL не нужно, даже если текущий запрос еще не завершился.

Повторный XmlHttp-запрос после abort() зависает

С этой проблемой я сталкивался только в IE под Windows. Ее причины — в том, что abort() не обрывает TCP-соединение, а оставляет его висеть до наступления таймаута (см. метод abort()). Если же к домену есть два TCP-соединения (даже ждущие таймаута), то третье будет висеть, пока какое-то из них не помрет.

XmlHttpRequest виснет в IE7 (много табов)

Проблема иногда возникает при отладке приложений с длинными XmlHttpRequest, которые висят и ждут события с сервера.

Она связана с ограничением в 2 одновременных соединения к одному домену. Точнее, с тем фактом, что это ограничение в IE7 действует не на один таб, а на все. Так что, если есть два таба с непрерывным соединением, то при открытии третьего таба — XmlHttpRequest с него к тому же домену просто зависнет и будет ждать окончания одного из двух предыдущих запросов.

Утечки памяти

В Internet Explorer объект XmlHttpRequest принадлежит миру DOM/COM, а Javascript-функция — миру Javascript. Присваивание xmlhttp.onreadystatechange = function() { ... } задает неявную
круговую связь: xmlhttp ссылается на функцию через onreadystatechange, а функция, через свою область видимости — видит (ссылается на) xmlhttp.

Невозможность обнаружить и оборвать такую связь во многих (до IE 6,7 редакции июня 2007?) версиях Internet Explorer приводит к тому, что XmlHttpRequest вместе
с ответом сервера, функция-обработчик и всё замыкание прочно оседают в памяти до перезагрузки браузера.

Чтобы этого избежать, ряд фреймворков (YUI, dojo…) вообще не ставят onreadystatechange, а вместо этого через setTimeout проверяют его readyState каждые 10 миллисекунд.
Это разрывает круговую связку xmlhttp onreadystatechange, и утечка памяти не грозит даже в самых глючных браузерах.

Firefox ставит responseXML вида …

Да, у браузеров типа Mozilla это такой способ сказать, что документ невалидный.

Ограничения безопасности. Кросс-доменный XMLHttpRequest

Для ограничения XmlHttpRequest используется философия «Same Origin Policy». Она очень проста — каждый сайт в своей песочнице. Запрос можно делать только на адреса
с тем же протоколом, доменом, портом, что и текущая страница.

Т.е, со страницы на адресе http://site.com нельзя сделать XmlHttpRequest на адрес https://site.com, http://site.com:81 или http://othersite.com

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

Проксирование

Самый простой способ обойти это ограничение — проксирование. Допустим, мы хотим сделать запрос с http://site.com на http://remote.com/get.html.

Чтобы обойти ограничение, вместо указания remote.com в методе open(), там ставится специальный URL вида http://site.com/proxy/remote.com/get.html. Так что запрос приходит на наш веб-сервер, который проксирует его на сервер site.com, который в свою очередь обрабатывает этот запрос, как нужно.

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

Проксирование настраивается соответствующим модулем (mod_proxy, proxy module и т.п.) веб-сервера для всех адресов, начинающихся на /proxy.

Например, при использовании web-сервера Apache, для проксирования нужны директивы ProxyPass, ProxyPassReverse. Кроме того, доступны еще модули, которые по необходимости правят урлы, разархивируют контент и т.п.

Использование наддомена

Часто кроссбраузерные запросы — это

  1. Способ обойти ограничения в 2 одновременных соединения к одному домену-порту.
  2. Способ использовать два разных сервера в общении с посетителем. Например, на chat.site.ru — чат-демон, на www.site.ru — веб-сервер.

Кросс-доменные запросы с поддомена типа http://a.site.com, http://b.site.com на базовый домен site.com допустимы при использовании свойства document.domain, которое надо установить в site.com

// на странице a.site.com
...
document.domain='site.com'
...
// все, теперь могу делать XmlHttpRequest на site.com
xmlhttp.open(..'http://site.com/feedme.php'..)

Запрос на старый домен

В браузере Internet Explorer, чтобы сделать запрос на старый домен a.site.com, нужно вернуть свойство document.domain обратно. В остальных браузерах это приводит к ошибке, поэтому можно оформить код типа такого:

var oldDomain = document.domain
document.domain = "site.com"
try {
    // для IE, в остальных браузерах ошибка...
    document.domain = oldDomain;
} catch(e) {  /* ... но в них все и так работает */ }
//... работаем с a.site.com ...

Same origin и фреймы

Приятным бонусом свойства document.domain является возможность коммуникации между фреймами/ифреймами на одном домене.

То есть, например, если

  • во фрейме с адреса http://a.site.com установлен document.domain=’site.com’,
  • на фрейме с адреса http://b.site.com установлен домен document.domain=’site.com’
  • на фрейме с адреса http://site.com установлен (обязательно!) домен document.domain=’site.com’

То эти три фрейма могут свободно общаться посредством javascript и XmlHttpRequest.

Обычно такая коммуникация используется при создании чатов/событий с сервера, когда на site.com находится основной веб-сервер, а на chat.site.com висит чат-демон.

Internet Explorer trusted zone

Любые запросы допустимы между сайтами, находящимися в доверенной (trusted) зоне Internet Explorer. Так что, внутренний корпоративный портал может быть у всех пользователей в этой зоне, и он сможет делать запросы к любым сайтам.

XhrIframeProxy

Еще один хитрый подход называется XHRIframeProxy, и позволяет делать XmlHttpRequest к любым доменам при помощи хитрого iframe-хака. Он основан на том, что фреймы с разных доменов могут читать и менять друг у друга anchor, т.е часть адреса после решетки ‘#’. За счет этого организуется специальный протокол, по которому «проксируется» XmlHttpRequest.

Этот метод, в принципе, вполне жизнеспособен, особенно для небольшого объема данных.

Кросс-доменные запросы в FF3/IE8/Opera9..

В спецификации HTML 5 предусмотрены кросс-доменные запросы postMessage.

Создатели Firefox и Opera реализовали этот вариант, см. например MDC: DOM:window.postMessage.

Разработчики IE8 пошли другим путем и предлагают XDomainRequest.

Оба способа вполне жизнеспособны и уже пригодны для использования в интранет-приложениях, когда на всех машинах администратор ставит одинаковый браузер, например, Firefox 3 ?

Поддержка в библиотеках и фреймворках

Практически каждая javascript-библиотека или javascript-фреймворк включает в том или ином виде поддержку XmlHttpRequest-запросов и других способов прозрачного общения с сервером. Берите фреймворк по другим
параметрам, а какая-то поддержка так обязательно будет.

Javascript-библиотеки

Dojo toolkit

Наиболее профессионально общение с сервером, на мой взгляд, сделано в dojo. Для удобства работы с асинхронными вызовами, в
dojo и Mochikit используется специальный объект Deferred. Умеет посылать формы, отменять запросы, позволяет строить сложные цепочки асинхронных вызовов. В dojo для этого используется вызов dojo.xhrGet, который позволяет указывать обработчик, таймаут и формат запроса (например, JSON). Также умеет предотвращать кеширование (preventCache), передавать объекты/формы с файлами.

Надо сказать, что в dojo есть еще масса других транспортов, которые позволяют вытворять со связью клиент-сервер все, что только возможно и невозможно… Надо только разобраться как, на момент написания доки, откровенно говоря, слабоваты.

Yahoo UI (YUI)

В Yahoo UI соединениями с сервером заведует Connection Manager. Главная фунция asyncRequest принимает в качестве одного из параметров (callback) объект, который позволяет подписываться на события, указывать timeout и посылать на сервер объект. Кроме того можно указывать временной промежуток для автоматических опросов. Например, опрашивать новости с сервера каждые 3 секунды. Метод setForm передает форму, умеет загружать файлы.

Prototype

Во фреймворке prototype Ajax представлен рядом классов вида Ajax.*. В сочетании с другими методами библиотеки — предоставляет весь стандартный функционал. Кроме того — приятный бонус: Ajax.PeriodicalUpdater умеет легко обновлять HTML-элемент с сервера и гибко увеличивать промежуток между опросами при проблемах серверной части.

JsHttpRequest

Есть еще библиотека JsHttpRequest, которая набрала популярность за счет русской документации и коммунити. Весь базовый функционал у нее есть. Лично я ни разу не пользовался, но говорят — работает. Если Вы не знаете английского языка и не нуждаетесь в интеграции AJAX с более общим javascript-фреймворком — возможно, эта библиотека подойдет.

Серверные библиотеки

Есть специальные серверные библиотеки, которые упрощают работу с XmlHttpRequest, организуя не только javascript-часть, но и серверную тоже. Они обычно умеют, например, отображать серверные функции на php в javascript-аналоги. При вызове такого javascript-аналога библиотека сама сделает запрос на сервер, обработает его на сервере, вызовет серверную функцию и вернет ее результат.

Для PHP одной из лучших библиотек является XAJAX, для Java — DWR.

…А если…

… Ну а если фреймворка не хочется, или надо то, чего во фреймворках нет, надеюсь, после прочтения этой доки, Вы без проблем реализуете все сами.

Источник: http://xmlhttprequest.ru

Ajax Документация

Понравилась статья? Поделить с друзьями:
  • He cleaned the windows and earned 20
  • He came into the room to shut the windows while
  • Hdwificam pro для windows 10 x64
  • Hds honda скачать для windows 7
  • Hds him установка на windows 10