Ошибка object xmlhttprequest

Симптомы

Используется в модуле URLMON в Internet Explorer 9 или в Internet Explorer 10 для установления нового подключения HTTPS. Если для подключения требуется сертификат клиента, объект XMLHttpRequest (объект JavaScript) не может отправлять данные.

Решение

Сведения об обновлении

Чтобы устранить эту проблему, установите последний накопительный пакет обновления для системы безопасности для Internet Explorer.

Для установки этого обновления, перейдите в Центр обновления Microsoft. Чтобы установить данное обновление, обратитесь к разделу «Сведения о реестре».

Технические сведения о самых последних накопительное обновление безопасности для обозревателя Internet Explorer посетите следующий веб-узел корпорации Майкрософт:

2888505 MS13-088: Накопительное обновление безопасности для обозревателя Internet Explorer: 12 ноября 2013

Сведения о реестре

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

После установки обновления, необходимо изменить реестр. Чтобы сделать это, выполните следующие действия.

Для 32-разрядных компьютерах (на основе x86)

  1. Нажмите кнопку Пуск, выберите пункт Выполнить, введите команду regedit и нажмите кнопку ОК.

  2. Откройте следующий раздел:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl

  3. Щелкните правой кнопкой мыши FeatureControl, выберите пункт Создатьи выберите раздел.

  4. Введите FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776и нажмите клавишу ВВОД, чтобы имя нового раздела.

  5. Щелкните правой кнопкой мыши FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776, выберите команду Создатьи затем щелкните Значение DWORD.

  6. Введите iexplore.exeи нажмите клавишу ВВОД, чтобы присвоить имя новой записи.

  7. Щелкните правой кнопкой мыши iexplore.exeи нажмите кнопку Изменить.

  8. В поле значение введите 00000001и нажмите кнопку ОК.

  9. Закройте редактор реестра.


Для 64-разрядных компьютерах (на основе x64)

  1. Нажмите кнопку Пуск, выберите пункт Выполнить, введите команду regedit и нажмите кнопку ОК.

  2. Откройте следующий раздел:

    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl

  3. Щелкните правой кнопкой мыши FeatureControl, выберите пункт Создатьи выберите раздел.

  4. Введите FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776и нажмите клавишу ВВОД, чтобы имя нового раздела.

  5. Щелкните правой кнопкой мыши FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776, выберите команду Создатьи затем щелкните Значение DWORD.

  6. Введите iexplore.exeи нажмите клавишу ВВОД, чтобы присвоить имя новой записи.

  7. Щелкните правой кнопкой мыши iexplore.exeи нажмите кнопку Изменить.

  8. В поле значение введите 00000001и нажмите кнопку ОК.

  9. Откройте следующий раздел:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl

  10. Щелкните правой кнопкой мыши FeatureControl, выберите пункт Создатьи выберите раздел.

  11. Введите FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776и нажмите клавишу ВВОД, чтобы имя нового раздела.

  12. Щелкните правой кнопкой мыши FEATURE_SHOW_CERT_WARNINGS_ON_POST_FROM_ISTREAM_KB2894776, выберите команду Создатьи затем щелкните Значение DWORD.

  13. Введите iexplore.exeи нажмите клавишу ВВОД, чтобы присвоить имя новой записи.

  14. Щелкните правой кнопкой мыши iexplore.exeи нажмите кнопку Изменить.

  15. В поле значение введите 00000001и нажмите кнопку ОК.

  16. Закройте редактор реестра.

Ссылки

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

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.

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

I’m using XMLHttpRequest in JavaScript. However, it gives me an error, and I don’t know what my problem is.
I have to parse an XML file and assign its contents to the webpage — here’s my code:

<script = "text/javascript">

    window.onload = onPageLoad();
    var questionNum = 0;

    function onPageLoad(questionNum) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET","quiz.xml");
        try {
            xmlhttp.send(null); // Here a xmlhttprequestexception number 101 is thrown 
        } catch(err) {
            document.getElementById("body").innerHTML += "\nXMLHttprequest error: " + err.description; // This prints "XMLHttprequest error: undefined" in the body.
        }
        xmlDoc = xmlhttp.responseXML;
        parser = new DOMParser(); // This code is untested as it does not run this far.
    }
</script>

My XML file is inside the same directory.

<question>
    <query>what is 2+2?</query>
    <option>4</option>
    <option>5</option>
    <option>3</option>
    <answer>4</answer>
</question>

Just for reference, I typically program in C# or Java, and I’m running my website on Google Chrome.

Davide Cannizzo's user avatar

asked Jan 15, 2012 at 0:59

Muricula's user avatar

So there might be a few things wrong here.

First start by reading how to use XMLHttpRequest.open() because there’s a third optional parameter for specifying whether to make an asynchronous request, defaulting to true. That means you’re making an asynchronous request and need to specify a callback function before you do the send(). Here’s an example from MDN:

var oXHR = new XMLHttpRequest();

oXHR.open("GET", "http://www.mozilla.org/", true);

oXHR.onreadystatechange = function (oEvent) {
    if (oXHR.readyState === 4) {
        if (oXHR.status === 200) {
          console.log(oXHR.responseText)
        } else {
           console.log("Error", oXHR.statusText);
        }
    }
};

oXHR.send(null);

Second, since you’re getting a 101 error, you might use the wrong URL. So make sure that the URL you’re making the request with is correct. Also, make sure that your server is capable of serving your quiz.xml file.

You’ll probably have to debug by simplifying/narrowing down where the problem is. So I’d start by making an easy synchronous request so you don’t have to worry about the callback function. So here’s another example from MDN for making a synchronous request:

var request = new XMLHttpRequest();
request.open('GET', 'file:///home/user/file.json', false); 
request.send(null);

if (request.status == 0)
    console.log(request.responseText);

Also, if you’re just starting out with Javascript, you could refer to MDN for Javascript API documentation/examples/tutorials.

kefir500's user avatar

kefir500

4,1946 gold badges42 silver badges48 bronze badges

answered Jan 15, 2012 at 1:39

Nadir Muzaffar's user avatar

Nadir MuzaffarNadir Muzaffar

4,7722 gold badges32 silver badges48 bronze badges

7

I see 2 possible problems:

Problem 1

  • the XMLHTTPRequest object has not finished loading the data at the time you are trying to use it

Solution:
assign a callback function to the objects «onreadystatechange» -event and handle the data in that function

xmlhttp.onreadystatechange = callbackFunctionName;

Once the state has reached DONE (4), the response content is ready to be read.

Problem 2

  • the XMLHTTPRequest object does not exist in all browsers (by that name)

Solution:
Either use a try-catch for creating the correct object for correct browser ( ActiveXObject in IE) or use a framework, for example jQuery ajax-method

Note: if you decide to use jQuery ajax-method, you assign the callback-function with jqXHR.done()

answered Jan 15, 2012 at 1:13

supertopi's user avatar

supertopisupertopi

3,46926 silver badges38 bronze badges

The problem is likely to lie with the line:

window.onload = onPageLoad();

By including the brackets you are saying onload should equal the return value of onPageLoad(). For example:

/*Example function*/
function onPageLoad()
{
    return "science";
}
/*Set on load*/
window.onload = onPageLoad()

If you print out the value of window.onload to the console it will be:

science

The solution is remove the brackets:

window.onload = onPageLoad;

So, you’re using onPageLoad as a reference to the so-named function.

Finally, in order to get the response value you’ll need a readystatechange listener for your XMLHttpRequest object, since it’s asynchronous:

xmlDoc = xmlhttp.responseXML;
parser = new DOMParser(); // This code is untested as it doesn't run this far.

Here you add the listener:

xmlHttp.onreadystatechange = function() {
    if(this.readyState == 4) {
        // Do something
    }
}

Davide Cannizzo's user avatar

answered Jan 15, 2012 at 1:16

CBusBus's user avatar

CBusBusCBusBus

2,3211 gold badge18 silver badges26 bronze badges

2

Здесь Вы найдете полное описание объекта 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 Документация

When you stick to old habits and create a network request with XMLHttpRequest in the Node runtime environment, you might see the “XMLHttpRequest is not defined” Error in JavaScript. This article will explain why your script couldn’t run like on your browser and how to fix that issue.

Reproduce The Error

Let’s say you have this JavaScript file:

var req = new XMLHttpRequest();
req.open("GET", "https://learnshareit.com/example.json");

This script is designed to create an XMLHttpRequest object on the server and use it to fetch a JSON file, making it ready for data exchange between the server and client.

However, when we run this script with Node.js, an error appears instead:

var req = new XMLHttpRequest();
          ^
ReferenceError: XMLHttpRequest is not defined

The error happens because, by default, Node.js doesn’t come with anything to handle XMLHttpRequest (XHR) objects. While XMLHttpRequest is widely used in AJAX, only browsers (client side) have support for it out of the box.

At the end of the day, W3C defines XMLHttpRequest as an API providing client features for transferring data between it and a server. There is no reason for Node.js to implement and make it a native API.

To solve the problem, you must find third-party solutions that can simulate XMLHttpRequest on the server side. Another choice is to replace it with other libraries with the same functionality.

xmlhttprequest

The node-XMLHttpRequest module is written to emulate the XMLHttpRequest object.

Install it with npm:

npm install xmlhttprequest

Or add it to the package.json file:

{
  "dependencies": {
    "xmlhttprequest": "*"
  }
}

Keep in mind that the current version only supports XMLHttpRequest Level 1. You will need to include the module first before calling the XMLHttpRequest() like usual to create a browser-based XHR object:

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var req = new XMLHttpRequest();
req.open("GET", "https://learnshareit.com/example.json");

xhr2

The xhr2 module is newer and also implements the XMLHttpRequest Level 1 specification using native APIs of Node.js.

Install it with npm:

npm install xhr2

Or add it to the package.json file:

{
  "dependencies": {
    "xhr2": "*"
  }
}

Include the module it before calling the XMLHttpRequest() constructor:

var XMLHttpRequest = require('xhr2');
var req = new XMLHttpRequest();
req.open("GET", "https://learnshareit.com/example.json");

It is important to note that xhr2 doesn’t implement some standard features of the W3C XMLHttpRequest specifications, including:

  • cookie processing
  • synchronous operation
  • events for upload progress
  • data: URIs
  • file:// URIs
  • Blog
  • FormData

Fetch API

XMLHttpRequest still exists mainly for historical reasons. The browser still needs to support it for compatibility since many legacy scripts use this object.

When possible, you should replace it with modern APIs like Fetch. Like XMLHttpRequest, it can also send network requests and receive new information when needed. You can use it to get new updates from a server and submit a form without reloading the page.

On the server side, you can install the node-fetch module, an API compatible with client-side  ‘window.fetch’.

Install it with npm:

npm install node-fetch

Or add it to the package.json file:

{
  "dependencies": {
    "node-fetch": "*"
  }
}

And rewrite your code with it:

import fetch from 'node-fetch';
let response = await fetch("https://learnshareit.com/example.json");
if (response.ok) {
    let json = await response.json();
    } else {
    alert("Error: " + response.status);
}

The response object returned by the fetch() function has many promise-based methods, such as:

  • response.json(): allow you to parse the response as a JSON source
  • response.text(): return the response as text

Summary

The “XMLHttpRequest is not defined” Error in JavaScript occurs when you call the XMLHttpRequest() constructor in a Node.js environment. This is a browser-based API, and you will need additional modules or other server-side replacements.

Maybe you are interested:

  • Solving The Error “No Value Accessor For Form Control With Name”
  • ReferenceError: document is not defined in JavaScript

Robert J. Charles

My name is Robert. I have a degree in information technology and two years of expertise in software development. I’ve come to offer my understanding on programming languages. I hope you find my articles interesting.


Job: Developer
Name of the university: HUST
Major: IT
Programming Languages: Java, C#, C, Javascript, R, Typescript, ReactJs, Laravel, SQL, Python

When working with JavaScript, encountering errors is a common occurrence for developers. One such error that often puzzles programmers is the “ReferenceError: XMLHttpRequest is not defined

In this article, we will explore the reasons behind the “ReferenceError: XMLHttpRequest is not defined” error and provide practical solutions to fix it.

The error “ReferenceError: XMLHttpRequest is not defined” indicates that the code is trying to use the XMLHttpRequest object, but it is not recognized or available in the current context.

XMLHttpRequest is a built-in JavaScript object that allows making HTTP requests from a web page to retrieve data from a server.

Additionally, it is commonly used for AJAX (Asynchronous JavaScript and XML) operations, where data can be fetched from a server without refreshing the entire page.

There are a few possible reasons for encountering this error:

  • Compatibility: The XMLHttpRequest object is not supported in all environments or versions of JavaScript.
  • Misspelling or Typo: There might be a typographical error in the code, such as misspelling the object name as “xmlhttprequest” instead of “XMLHttpRequest”.
  • Scope: The code is trying to access the XMLHttpRequest object outside of its defined scope.

Referenceerror Example

Here’s an example program that could result in a “ReferenceError: XMLHttpRequest is not defined” error:

// Attempting to use XMLHttpRequest
var xhr = new XMLHttpRequest(); // Error occurs here
xhr.open("GET", "https://api.example.com/data", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();

In this example, the code attempts to create a new XMLHttpRequest object and perform a GET request to fetch data from an API endpoint.

However, if you execute this code in an environment that lacks support or definition for the XMLHttpRequest object, it will result in the “ReferenceError: XMLHttpRequest is not defined” error being thrown.

How to fix Referenceerror: xmlhttprequest is not defined?

To fix the “ReferenceError: XMLHttpRequest is not defined” error in your code, you can consider the following solutions:

Solution 1: Use the Fetch API

The Fetch API is a modern JavaScript API for making HTTP requests. It is widely supported in modern browsers and provides a more straightforward and flexible syntax compared to XMLHttpRequest.

Here’s an example of how you can rewrite your code using the Fetch API:

fetch("https://api.example.com/data")
  .then(response => {
    if (response.ok) {
      return response.text();
    } else {
      throw new Error('HTTP status ' + response.status);
    }
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

Solution 2: Use a library like Axios

Axios is a popular JavaScript library for making HTTP requests.

It provides a simple and powerful API and is compatible with both browsers and Node.js.

To use Axios, you need to include the library in your project.

Here’s an example:

// Include Axios library (you can download it or use a CDN)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

// Make an HTTP GET request
axios.get("https://api.example.com/data")
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

Solution 3: Compatibility and Environment Check

If you’re not operating in a browser environment, the availability of the XMLHttpRequest object might be limited.

Confirm that your code is being executed in an environment that supports XMLHttpRequest, or explore alternative methods suited for your specific environment.

Solution 4: Code Execution Context Verification

Ensure that you are attempting to use the XMLHttpRequest object within the correct scope.

If necessary, verify if the code is placed inside a function or event handler that is being appropriately called.

Solution 5: Spelling and Capitalization Check

Thoroughly review the spelling and capitalization of the XMLHttpRequest object.

Confirm that it is written precisely as “XMLHttpRequest,” with the exact same casing.

By implementing these solutions, you should be able to resolve the “ReferenceError: XMLHttpRequest is not defined” error and successfully execute the HTTP request in your code.

Anyway, here are other fixed errors you can refer to when you might encounter them.

  • Referenceerror: exports is not defined in es module scope
  • Referenceerror: localstorage is not defined

Conclusion

In conclusion, the “ReferenceError: XMLHttpRequest is not defined” error occurs when attempting to use the XMLHttpRequest object in JavaScript code, but it is not recognized or available in the current context.

We hope this guide has assisted you in resolving the error effectively.

Until next time! 😊

Понравилась статья? Поделить с друзьями:
  • Ошибка obi элинж с3т
  • Ошибка oct на частотнике ls
  • Ошибка kernel auto boost invalid lock release
  • Ошибка obf на частотном преобразователе schneider
  • Ошибка kerbal space program