XMLHttpRequest status 0 (responseText порожній)


104

Неможливо отримати дані за допомогою XMLHttpRequest (статус 0 та відповідьText порожній):

xmlhttp = новий XMLHttpRequest ();
xmlhttp.open ("GET", "http://www.w3schools.com/XML/cd_catalog.xml", правда);
xmlhttp.onreadystatechange = функція () 
{
  якщо (xmlhttp.readyState == 4)
    попередження ("статус" + xmlhttp.status);
}
xmlhttp.send ();

Він попереджає "статус 0".

Така ж ситуація з запитом localhost (cd_catalog.xml зберігається як локальний файл)

xmlhttp.open ("GET", "http: //localhost/cd_catalog.xml", правда);

Але з IP-адресою localhost IP

xmlhttp.open ("GET", "http://127.0.0.1/cd_catalog.xml", правда);

і з запитом локального файлу

xmlhttp.open ("GET", "cd_catalog.xml", правда);

все гаразд (статус 200)

Що може спричинити проблему (статус = 0) із запитом в Інтернеті?

PS: Заголовки HTTP Live показують, що у всіх 4 випадках все гаразд:

  HTTP / 1.1 200 ОК
  Довжина вмісту: 4742

PS2: локальний веб-сервер Apache на VMWare (хост ОС Win7, гостьова ОС Ubuntu, мережевий адаптер - NAT). Браузер - Firefox.


1
Чи http://127.0.0.1є випадково ваша тестова сторінка ? ;)
Roatin Marth


7
Ви відповіли на своє запитання. XMLHttpRequestне може робити запити між доменами. Однак є деякі шляхи вирішення. Подивіться, наприклад, jquery.
мезе

Використовуйте php, щоб отримати файл. Невеликий обхід: jquery-howto.blogspot.com/2009/04/…

2
@meze: міждоменні дзвінки працюють з jQuery. Але як це не може працювати з звичайним JavaScript, оскільки jQuery реалізований у JavaScript? Це для мене немає сенсу. Чи використовує jQuery якийсь неприємний спосіб вирішення?
Грубер

Відповіді:


55

статус 0, коли ваш HTML-файл, що містить сценарій, відкривається у браузері за допомогою файлової схеми. Переконайтесь, що розмістіть файли на своєму сервері (apache або tomcat як завгодно), а потім відкрийте їх через протокол http у браузері. (тобто http: //localhost/myfile.html ) Це рішення.


1
Чому це заборонено? Це насправді правда! XHR запити з файлу: // URL-адреси файлів також у файлі: // URL-адреси насправді мають статус == 0 при успішності (перевірено на FF 24.0.5).
Даніель Ретлісбергер

3
Я також отримую статус == 0 на успіх у Safari версії 6.1.6.
Планар

У мене є статус = 0 (але статус 200 у мережі), використовуючи Завантажити тимчасовий надбудову на firefox
JobaDiniz

1
все ще дійсна відповідь. Відповідь HTTP становить 200 для фактичних віддалених схем (http та ін.) Та 0 для локального файлу ( file://схеми). Очевидно, вам потрібно дозволити спочатку завантажувати локальний файл, відключивши CORS.
pid

31

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

Якщо ви займаєтеся розробкою localhost, ви можете здійснювати міждоменні дзвінки - я це роблю постійно.

Для Firefox ви повинні ввімкнути його у своїх налаштуваннях конфігурації

signed.applets.codebase_principal_support = true

Потім додайте щось подібне до відкритого коду XHR:

  if (isLocalHost()){
    if (typeof(netscape) != 'undefined' && typeof(netscape.security) != 'undefined'){
      netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
    }
  }

Для IE, якщо я добре пам’ятаю, все, що вам потрібно зробити, - це включити налаштування безпеки браузера в розділі «Різне → Доступ до джерел даних для доменів», щоб він працював з ActiveX XHR.

IE8 і вище також додали можливості міждоменних програм до власних об'єктів XmlHttpRequest, але я ще не грав з ними.


8
Якщо комусь це потрібно, для Chrome потрібно запустити його новий екземпляр (без жодного вже відкритого) та використовувати--allow-file-access-from-files
TheZ

@TheZ: Ви на 100%? Я чув, що вам потрібно запустити лише новий екземпляр Chrome із --allow-file-access-from-filesперемикачем, але не потрібно закривати всі інші запущені екземпляри. Так само, як і в режимі анонімного перегляду Chrome - ви можете ним користуватися, не закриваючи жодних інших запущених екземплярів.
trejder

Схоже, підтримка "UniversalBrowserRead" відпала, тому ця робота навколо не є можливою.
perilandmishap

Також це може статися, коли ви запитуєте http-сторінку зі сторінки https (наприклад, розширення в браузері).
sibvic

Я зіткнувся з цією проблемою, незважаючи на сторінку html та скрипт AJAX, що знаходиться в одному домені. Але дивно, це впливає лише на деякі сценарії, особливо на будь-які сценарії, що мають доступ до ресурсів MongoDB. Будь-які підказки, чому це так?
Девід Едвардс

26

Насправді переконайтесь, що ваш тип кнопки - кнопка "Не надсилати", що спричинило конфлікт у статусі, де я нещодавно зустрічався.


1
Виникає конфлікт, оскільки при надходженні форми є деяка поведінка за замовчуванням, яку потрібно запобігти, якщо ви обробляєте подію та здійснюєте дзвінок в Ajax самостійно. Ви можете запобігти поведінці за замовчуванням, взявши подію у свого обробника та зателефонувавшиe.preventDefault()
Йордан

20

Якщо сервер відповідає методом OPTIONS та GET і POST (залежно від того, який з них ви використовуєте) із заголовком типу:

Access-Control-Allow-Origin: *

Це може спрацювати нормально. Здається, у FireFox 3.5 та rekonq 0.4.0. Мабуть, із цим заголовком та початковою відповіддю на ВАРІАНТИ сервер каже браузеру: "Ідіть і нехай цей запит між доменним шляхом проходить".


3
Це правильна відповідь! Перегляньте en.wikipedia.org/wiki/Cross-origin_resource_sharing для отримання додаткової інформації. Якщо додати цей заголовок, він не може "працювати", але "буде працювати". Примітка. Вам потрібно додати HTTP / відповідь / заголовок, тому ви можете це робити лише на сервері, яким ви керуєте. Ніколи не вдасться безпосередньо отримати w3schools.com/XML/cd_catalog.xml за допомогою XMLHttpRequest(тобто, відповідно до оригінального запитання), оскільки цей ресурс не містить (принаймні, на 24 квітня 2015 року) жодного такого заголовка CORS.
MikeBeaton

13

Розглянемо також час очікування запиту :

Сучасний браузер повертає ReadyState = 4 і s tatus = 0, якщо до відповіді сервера проходить занадто багато часу.


3
@AndreaSavojardo: Чи є у вас якісь посилання (наприклад, повідомлення на MDN) про те, чи відповідає ця поведінка стандартам?
Олександр Абакумов

@AndreaSavojardo У мене ReadyState = 4 і статус = 0, і сервер не працює, але попередження про помилку показується мені швидко .... скільки часу проходить для "time time out"?

7

Додати setRequestHeader("Access-Control-Allow-Origin","*")до відповіді вашого сервера.


3

Я зіткнувся з подібною проблемою. Все було в порядку, "Readystate" було 4, але "статус" було 0. Це було тому, що я використовував портативний сервер Apache PHP, і мій файл, в якому я використовував "XMLHttpRequest", був файлом html. Я змінив розширення файлу на php і проблема була вирішена.


3

Відкрити консоль javascript . Ви побачите там повідомлення про помилку. У моєму випадку це був CORS.


2

Щоб відповісти на питання, чому http://127.0.0.1/cd_catalog.xmlпрацює поки http://localhost/cd_catalog.xmlщо, Firefox розглядає 127.0.0.1 і localhost як два різні домени.


2

Щоб побачити, у чому проблема, коли ви отримаєте криптовалютну помилку 0, перейдіть до ... | Інші інструменти | Інструменти для розробників (Ctrl + Shift + I) у Chrome (на сторінці із помилкою)

Прочитайте червоний текст у журналі, щоб отримати справжнє повідомлення про помилку. Якщо там занадто багато, клацніть правою кнопкою миші та Очистити консоль, а потім повторіть останній запит.

Перша моя проблема полягала в тому, що я вперше передав заголовки авторизації в свій власний веб-сервер між доменних веб-служб.

У мене вже було:

Access-Control-Allow-Origin: *

Але ні:

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization

у заголовку відповідей моєї веб-служби.

Після того, як я додав це, мій нуль помилки був знищений з мого власного веб-сервера, а також під час запуску файла index.html локально без веб-сервера, але все ж давав помилки в ручці коду.

Назад до ... | Інші інструменти | Інструменти для розробників при отриманні помилки в codepen, і там чітко пояснено: codepen використовує https, тому я не можу телефонувати на http, оскільки безпека нижча.

Тому мені потрібно розмістити свій веб-сервіс на https.

Знаючи, як отримати справжнє повідомлення про помилку - безцінне!


Я використав цей підхід (f12 в хромі) і виявив, що намагаюся перейти від https до http, який мовчки не вдавався, не надаючи нічого корисного. ПОВІДОМЛЕННЯ ПОМИЛКИ: VM1152: 1 Змішаний вміст: Сторінка на 'https://mysiteoriginsite' завантажена через HTTPS, але запитала незахищену кінцеву точку XMLHttpRequest 'http://MyDestinationSite/MyService.svc'. Цей запит заблоковано; вміст повинен подаватися через HTTPS.
GrayDwarf

1

Ось ще один випадок, коли status === 0конкретний для завантаження:

Якщо ви приєднаєте 'load'обробник подій до XHR.upload, як це запропонував MDN (прокрутіть вниз до частини завантаження «Моніторинг прогресу»), об’єкт XHR матиме, status=0а всі інші властивості будуть порожніми рядками. Якщо ви 'load'приєднаєте обробник безпосередньо до об'єкта XHR, як це було б під час завантаження вмісту, вам слід добре (враховуючи, що ви не біжите з localhost).

Однак, якщо ви хочете отримати хороші дані в 'progress'обробниках подій, вам потрібно приєднати обробник XHR.upload, а не безпосередньо до самого об'єкта XHR.

Я поки що це тестував лише на Chrome OSX, тому я не впевнений, яка проблема тут полягає в документації MDN і наскільки це реалізація Chrome ...


1

Алекс Робінсон вже (і перший) дає правильну відповідь на це питання. Але допрацювати це трохи більше ...

Ви повинні додати заголовок відповіді HTTP:

Access-Control-Allow-Origin: *

Якщо ви це зробите, результат не просто "може працювати", але "буде працювати".

Примітка. Вам потрібно додати заголовок відповіді HTTP - так ви можете це робити лише на сервері, яким ви керуєте. Ніколи не вдасться безпосередньо отримати http://w3schools.com/XML/cd_catalog.xml з його вихідної URL-адреси за допомогою XMLHttpRequest(відповідно до запитання ОП), оскільки цей ресурс не є (принаймні, не станом на 24 квітня 2015 р.) включити будь-який такий заголовок CORS.

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing дає більше інформації.


0

Мою проблему, подібну до цієї, вирішили, перевіривши мій html-код. У мене був onclickобробник у моїй кнопці подання форми до методу. подобається це: onclick="sendFalconRequestWithHeaders()". Цей метод, у свою чергу, називає ajax так само, як ваш, і робить те, що я хочу. Але не так, як очікувалося, мій браузер нічого не повертав.

Дізнавшись з чиєїсь важкої праці , я повернув помилку в цьому обробнику і вирішив. Дозвольте мені сказати , що до прибуття на цей пост, я витратив цілий 3-денний уїк - енд і півдня в офісі , написання коду , який реалізує CORS filters, jetty config, інший jersey and embedded jettyпов'язаний матеріал - просто , щоб виправити це, обертаючись все моє розуміння навколо.cross domain ajax requests . Це було смішно, як прості помилки в JavaScript роблять вас дурними.

Щоправда, я намагався signed.applets.codebase_principal_support = true і написав isLocalHost() **if**. може бути, цей метод нам повинен бути реалізований, Firefox каже, що такого немає. Тепер я маю очистити свій код, щоб чисто представити git patch. Завдяки цьому хтось.


0

Запит браузера "127.0.0.1/somefile.html" надходить без змін на локальний веб-сервер, тоді як "localhost / somefile.html" може надходити як "0: 0: 0: 0: 0: 0: 0: 1 / somefile.html "якщо підтримується IPv6. Таким чином, остання може бути оброблена як перехід від домену до іншого.


0

Алекс Робінсон та bmju надали цінну інформацію, щоб зрозуміти проблеми перехресного походження. Я хотів би додати, що вам може знадобитися зробити явний дзвінок OPTIONS у вашому коді клієнта перед тим, як зробити бажаний GET / POST (наприклад, проти кінцевої точки служби CORS OAuth). Ваш веб-переглядач / бібліотека може не обробляти автоматично запит OPTIONS. Грубер, це одна з можливих відповідей на ваше запитання.


0

У мене була така ж проблема (ReadyState було 4 і статус 0) , тоді я дотримувався іншого підходу, поясненого в цьому підручнику: https://spring.io/guides/gs/consuming-rest-jquery/

Він взагалі не використовував XMLHttpRequest , натомість використовував метод jquery $ .ajax () :

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="hello.js"></script>
</head>

<body>
    <div>
        <p class="greeting-id">The ID is </p>
        <p class="greeting-content">The content is </p>
    </div>
</body>

і для файлу public / hello.js (або ви можете вставити його безпосередньо в той самий код HTML):

$(document).ready(function() 
 {
    $.ajax({
        url: "http://rest-service.guides.spring.io/greeting"
   }).then(function(data) {
      $('.greeting-id').append(data.id);
      $('.greeting-content').append(data.content);
   });
 });

2
Ви розумієте, що jQuery $.ajax()використовує XMLHttpRequestзсередини, чи не так?
Манго

0

Мені довелося додати мою поточну IP-адресу (знову) до списку Atlas MongoDB, і так я позбувся помилки 0 статусу XMLHttpRequest


-1

У мене просто виникла ця проблема, тому що я використовував її 0.0.0.0як мій сервер, змінив її на localhostта працює.


-4

Редагувати: Прочитайте коментарі Мальволіо нижче, оскільки знання цієї відповіді застаріли.

Ви не можете робити міждоменні XMLHttpRequests.

Дзвінок 127.0.0.1працює, тому що ваша тестова сторінка розташована на 127.0.0.1, а локальний тест також працює, оскільки ... це локальний тест.

Інші два тести провалюються, оскільки JavaScript не може спілкуватися з віддаленим сервером через XMLHttpRequest.

Ви можете замість цього розглянути будь-яке:

  • XMLHttp-запитайте власний сервер, щоб отримати ваш віддалений вміст XML для вас (наприклад, php-скрипт)
  • Спроба використовувати такий сервіс, як GoogleAppEngine, якщо ви хочете, щоб він був повним JavaScript.

Сподіваюся, що це допомагає


40
Це просто неправильно. Ви можете робити міждоменні XMLHttpRequests.
Мальволіо

1
"Ви не можете", як у "Не варто робити цього, тому що це ніколи не є доброю ідеєю"
Габріель Шпренгер

24
- досить справедливо, але я не знаю , якщо коментар є найкращим форумом для цього. Міждоменний XMLHttpRequests, безумовно, має деякі проблеми з безпекою, але вони пропонують усі інструменти, необхідні для вирішення цих проблем. Крім того, вони дозволяють веб-сайтам легко пропонувати послуги на інших веб-сайтах, використовувати CDN для поширення даних та швидше реагувати на запити користувачів. Якщо у вас є якісь конкретні запитання, ви можете надіслати мені повідомлення, а ще краще, опублікувати тут питання на ЗО і звернути на мене мою увагу.
Мальволіо

2
@GabrielSprenger: Крос-домен XMLHttpRequests - це не лише гарна ідея, але настільки поширена в наші дні, що НЕ робити їх у сучасному веб-додатку (за межами якогось HelloWorlds) - щось смішне. Будь-яка зовнішня послуга REST, яку споживає ваш додаток, вимагає крос-домену XMLHttpRequest. І тому все, що було додано до CORS.
Олександр Абакумов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.