2010-03-20 1 views
6

Я совершенно новичок в мире javascript и ajax, но стараюсь учиться.Что мне недостает в XMLHttpRequest?

Сейчас я тестирую XMLHttpRequest, и я не могу заставить работать даже самый простой пример. Это код, который я пытаюсь запустить

<script type="text/javascript"> 
     function test() { 
      xhr = new XMLHttpRequest(); 

      xhr.onreadystatechange = function() { 
       if (xhr.readyState == 4 && xhr.status == 200){ 
        var container = document.getElementById('line'); 
        container.innerHTML = xhr.responseText; 
       } else { 
        alert(xhr.status); 
       } 
      } 

      xhr.open('GET', 'http://www.google.com', true);     
      xhr.send(null); 
     } 
    </script> 

И я всегда получаю предупреждение со статусом 0. Я прочитал тонны перемычек об этом, и я не знаю, что мне не хватает. Буду признателен за любую помощь, спасибо!

ответ

13

Вы работаете в Same Origin Policy.

Если ваш код действительно запущен на www.google.com (что маловероятно), это приведет к ошибке.

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

Сделать XHR локальной переменной функции

var xhr = new XMLHttpRequest(); 

И относятся к нему с this внутри метода onreadstatechange.

if (this.readyState == 4 && this.status == 200){ 
// etc etc 
8

Исходя из David's answer:

Вы должны использовать относительный путь, чтобы остаться в пределах одной и той же политики происхождения. В противном случае большинство браузеров просто вернут пустые responseText и status == 0.

Как один из возможных способов обхода, вы можете настроить очень простой reverse proxymod_proxy, если вы используете Apache). Это позволит вам использовать относительные пути в вашем запросе AJAX, в то время как HTTP-сервер будет действовать как прокси-сервер для любого «удаленного» местоположения.

Основная директива по настройке обратного прокси-сервера в mod_proxy - это ProxyPass. Вы, как правило, использовать его следующим образом:

ProxyPass  /ajax/  http://google.com/ 

В этом случае браузер будет запрос /ajax/search?q=stack+overflow но сервер будет выполнять эти задачи, выступая в качестве посредника для http://google.com/search?q=stack+overflow.

1

+1 Даниэль и Дэвид за правильные ответы, я хотел бы добавить в комментарий, что очень мало случаев (если только вы просто не хотите узнать JS лучше), что вы должны напрямую использовать xhr vice, используя библиотека, подобная jQuery, которая была проверена и доказана миллионами разработчиков по всему миру. В нем также есть много других полезных функций, которые помогут вам в разработке ajax (например, анимации и DOM-манипуляции).

Пол

2

В дополнение к этому же вопросу происхождения политики, ваш alert в нелогичного месте. Когда вы используете XMLHttpRequest, функция, назначенная на xhr.onreadystatechange, будет вызываться всякий раз, когда изменяется readyState. readyState должен измениться (теоретически) от 0 (инициализировано) до 1 (отправлено) до 2 (загрузка) до 3 (интерактивный) до 4 (готово).

Что делает ваш код проверки readyState и посмотреть, если запрос завершен (if (xhr.readyState == 4)), а если нет, alertHTTP status code. Поскольку запрос еще не отправлен (или только что был отправлен), статус HTTP еще не должен быть.

В идеале, вы должны переместить alert внутри блока if, чтобы он знал, когда он закончит.