XMLHttpRequest durumu 0 (responseText boş)


105

XMLHttpRequest ile veri alınamıyor (durum 0 ve responseText boş):

xmlhttp = new XMLHttpRequest ();
xmlhttp.open ("GET", "http://www.w3schools.com/XML/cd_catalog.xml", doğru);
xmlhttp.onreadystatechange = işlev () 
{
  eğer (xmlhttp.readyState == 4)
    alert ("durum" + xmlhttp.status);
}
xmlhttp.send ();

"Durum 0" ı uyarır.

Localhost isteğiyle aynı durum (cd_catalog.xml yerel bir dosya olarak kaydedilir)

xmlhttp.open ("GET", "http: //localhost/cd_catalog.xml", doğru);

Ancak localhost IP isteği ile

xmlhttp.open ("GET", "http://127.0.0.1/cd_catalog.xml", doğru);

ve yerel dosya talebi ile

xmlhttp.open ("GET", "cd_catalog.xml", doğru);

herşey yolunda (durum 200)

Çevrimiçi talepte soruna (durum = 0) ne sebep olabilir?

Not: Canlı HTTP Başlıkları, 4 durumda da her şeyin yolunda olduğunu gösterir:

  HTTP / 1.1 200 Tamam
  İçerik Uzunluğu: 4742

PS2: VMWare üzerinde Apache yerel web sunucusu (ana işletim sistemi Win7, Konuk İşletim Sistemi Ubuntu, Ağ adaptörü - NAT). Tarayıcı - Firefox.


1
Test sayfanız http://127.0.0.1tesadüfen yerinde mi? ;)
Roatin Marth

Evet. <code> 127.0.0.1/CDCatalogTest.html </code>
arigasa

7
Sorunuzu cevapladınız. XMLHttpRequestalanlar arası istekler yapılamaz. Yine de bazı geçici çözümler var. Örneğin jquery'ye bakın.
meze

Dosyayı almak için php kullanın. Küçük çalışma: jquery-howto.blogspot.com/2009/04/…

2
@meze: Alanlar arası aramalar jQuery ile çalışır. Ancak jQuery JavaScript'te uygulandığı için düz JavaScript ile nasıl çalışmaz? Benim için hiçbir anlam ifade etmiyor. JQuery bir tür kötü çözüm mü kullanıyor?
Gruber

Yanıtlar:


55

Komut dosyasını içeren html dosyanız tarayıcıda dosya şeması aracılığıyla açıldığında durum 0'dır. Dosyaları sunucunuza (apache veya tomcat ne olursa olsun) yerleştirdiğinizden ve ardından tarayıcıda http protokolü aracılığıyla açtığınızdan emin olun. (örneğin, http: //localhost/myfile.html ) Bu çözümdür.


1
Bu neden reddediliyor? Aslında doğru! File: // dosyalarının URL'lerinden XHR istekleri aynı zamanda file: // adresinde de başarılı olur (FF 24.0.5'te test edilmiştir) URL'ler aslında status == 0'a sahiptir.
Daniel Roethlisberger

3
Ayrıca Safari 6.1.6 Sürümünde başarı için status == 0 alıyorum.
Planar

Firefox'ta geçici eklenti
yükle'yi

1
hala geçerli cevap. HTTP yanıtı, gerçek uzak şemalar için 200 (http ve diğerleri) ve yerel dosya ( file://şema) için 0'dır . Açıkçası, önce CORS'u devre dışı bırakarak yerel dosya yüklemesine izin vermeniz gerekir.
pid

32

Sorunlarınızın nedeni, etki alanları arası bir arama yapmaya çalışmanız ve başarısız olmasıdır .

Localhost geliştirme yapıyorsanız, alanlar arası aramalar yapabilirsiniz - bunu her zaman yaparım.

Firefox için, yapılandırma ayarlarınızda etkinleştirmeniz gerekir

signed.applets.codebase_principal_support = true

Ardından XHR açık kodunuza buna benzer bir şey ekleyin:

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

IE için, doğru hatırlıyorsam, tek yapmanız gereken tarayıcının ActiveX XHR'lerle çalışmasını sağlamak için "Çeşitli → Etki alanları arasında veri kaynaklarına erişim" altındaki Güvenlik ayarını etkinleştirmektir.

IE8 ve üstü, yerel XmlHttpRequest nesnelerine etki alanları arası yetenekleri de ekledi, ancak henüz onlarla oynamadım.


8
Herhangi birinin ihtiyacı olması durumunda, Chrome için yeni bir örneğini başlatmanız (zaten açık olmadan) ve kullanmanız gerekir--allow-file-access-from-files
TheZ

@TheZ:% 100 müsün? Yalnızca --allow-file-access-from-filesanahtarla Chrome'un yeni örneğini çalıştırmanız gerektiğini duydum , ancak diğer tüm çalışan örnekleri kapatmanız gerekmez . Tıpkı Chrome Gizli Mod durumunda olduğu gibi - çalışan diğer örnekleri kapatmadan onu kullanabilirsiniz.
trejder

Görünüşe göre 'UniversalBrowserRead' desteği kaldırıldı, bu nedenle bu geçici çözüm bir seçenek değil.
perilandmishap

Ayrıca, https sayfasından (tarayıcıdaki uzantı gibi) http sayfası talep ettiğinizde de olabilir.
sibvic

Aynı etki alanında bulunan html sayfası ve AJAX betiğine rağmen bu sorunla karşılaşıyorum . Ancak tuhaf bir şekilde, yalnızca bazı komut dosyalarını, özellikle de MongoDB kaynaklarına erişen tüm komut dosyalarını etkiliyor . Bunun neden olduğuna dair bir ipucu var mı?
David Edwards

26

Aslında düğme türünüzün Düğme Gönderilmedi olduğundan emin olun, bu da yakın zamanda tanıştığım yerde durum çakışmasına neden oldu.


1
Bir çatışma var çünkü bir form göndermek, olayı idare ediyorsanız ve bir ajax çağrısı yapıyorsanız, önlemeniz gereken bazı varsayılan davranışlara sahiptir. Olayı işleyicinize alarak ve arayarak varsayılan davranışı önleyebilirsinize.preventDefault()
Ürdün

20

Sunucu, SEÇENEKLER yöntemine ve GET ve POST'a (hangisini kullanıyor olursanız olun) aşağıdaki gibi bir başlıkla yanıt verirse:

Access-Control-Allow-Origin: *

İyi çalışabilir. FireFox 3.5 ve rekonq 0.4.0'da görünüyor. Görünüşe göre, bu başlık ve SEÇENEKLER'e verilen ilk yanıtla, sunucu tarayıcıya "Devam et ve bu alanlar arası isteğin geçmesine izin ver" diyor.


3
Bu doğru cevap! Daha fazla bilgi için en.wikipedia.org/wiki/Cross-origin_resource_sharing adresine bakın . Bu başlığı eklerseniz, "işe yarayabilir" değil, "çalışacaktır". NB Eklemeniz gereken şey bir HTTP / yanıt / başlıktır - bu nedenle bunu yalnızca sizin kontrol ettiğiniz bir sunucuda yapabilirsiniz. W3schools.com/XML/cd_catalog.xml dosyasını kullanarak XMLHttpRequest(yani orijinal soruya göre) doğrudan getirmek asla mümkün olmayacaktır , çünkü bu kaynak (en azından 24 Nisan 2015 itibariyle) bu tür herhangi bir CORS başlığını içermemektedir.
MikeBeaton

13

Ayrıca istek zaman aşımını da göz önünde bulundurun :

Sunucu yanıtından önce çok fazla zaman geçerse, modern tarayıcı readyState = 4 ve s tatus = 0 döndürür .


3
@AndreaSavojardo: Bu davranışın standartlara uygun olup olmadığına dair herhangi bir referansınız var mı (MDN'deki bir gönderi gibi)?
Alexander Abakumov

@AndreaSavojardo readyState = 4 ve status = 0 var ve sunucu çalışmıyor ancak hatanın uyarısı bana hızlı bir şekilde gösteriliyor .... "istek zaman aşımı" için ne kadar zaman geçiyor?

7

setRequestHeader("Access-Control-Allow-Origin","*")Sunucu yanıtınıza ekleyin .


3

Benzer bir sorunla karşılaşmıştım. Her şey yolundaydı, "okuma durumu" 4'tü, ancak "durum" 0'dı. Bunun nedeni, bir Apache PHP taşınabilir sunucusu kullanmam ve "XMLHttpRequest" nesnesini kullandığım dosyamın bir html dosyası olmasıydı. Dosya uzantısını php olarak değiştirdim ve sorun çözüldü.


3

JavaScript konsolunu açın . Orada bir hata mesajı göreceksiniz. Benim durumumda CORS idi.


2

Neden http://127.0.0.1/cd_catalog.xmlçalışıp çalışmadığı sorusuna cevap vermek gerekirse http://localhost/cd_catalog.xml: Firefox, 127.0.0.1 ve localhost'u iki farklı alan adı olarak ele alıyor.


2

0 şifreli hata aldığınızda sorunun ne olduğunu görmek için ... | Diğer Araçlar | Chrome'da Geliştirici Araçları (Ctrl + Üst Karakter + I) (hatayı veren sayfada)

Gerçek hata mesajını almak için günlükteki kırmızı metni okuyun. Orada çok fazla şey varsa sağ tıklayın ve Konsolu Temizle, ardından son isteğinizi tekrar yapın.

İlk sorunum, Yetkilendirme üstbilgilerini ilk kez tarayıcı için kendi etki alanları arası web hizmetime geçirmekti.

Zaten yapmıştım:

Access-Control-Allow-Origin: *

Ama değil:

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

web hizmetimin yanıt başlığında.

Bunu ekledikten sonra, sıfır hatam kendi web sunucumdan ve index.html dosyasını bir web sunucusu olmadan yerel olarak çalıştırırken gitti, ancak yine de kod kaleminde hatalar veriyordu.

Geri dön ... | Diğer Araçlar | Codepen'de hata alırken Geliştirici Araçları ve açıkça açıklanmıştır: codepen https kullanır, bu nedenle güvenlik daha düşük olduğu için http'ye çağrı yapamıyorum.

Bu nedenle web hizmetimi https'de barındırmam gerekiyor.

Gerçek hata mesajını nasıl alacağınızı bilmek - paha biçilemez!


Bu yaklaşımı kullandım (chrome'da f12) ve https'den http'ye geçmeye çalıştığımı öğrendim, bu da yararlı hiçbir şey sağlamadan sessizce başarısız oluyordu. HATA MESAJI: VM1152: 1 Karma İçerik: adresindeki sayfa 'https://mysiteoriginsite' HTTPS üzerinden yüklendi, ancak güvenli olmayan bir XMLHttpRequest uç noktası istedi 'http://MyDestinationSite/MyService.svc'. Bu istek engellendi; içerik HTTPS üzerinden sunulmalıdır.
GrayDwarf

1

İşte status === 0yüklemeye özgü başka bir durum :

MDN tarafından önerildiği gibi bir 'load'olay işleyicisini eklerseniz ('İzleme ilerlemesi'nin yükleme kısmına gidin), XHR nesnesi olacak ve diğer tüm özellikler boş dizeler olacaktır. Eğer eklerseniz XHR nesneye doğrudan işleyicisi içerik indirirken yaptığınız gibi, ince olmalıdır (localhost kapalı Kaçmıyoruz verilen).XHR.uploadstatus=0'load'

Ancak, 'progress'olay işleyicilerinizde iyi veriler elde etmek istiyorsanız XHR.upload, doğrudan XHR nesnesinin kendisine değil , ona bir işleyici eklemeniz gerekir .

Bunu şimdiye kadar yalnızca Chrome OSX'te test ettim, bu yüzden buradaki sorunun ne kadarının MDN'nin belgeleri olduğundan ve Chrome'un uygulamasının ne kadar olduğundan emin değilim ...


1

Alex Robinson zaten (ve önce) bu konuya doğru cevabı veriyor. Ama biraz daha detaylandırmak gerekirse ...

HTTP yanıt başlığını eklemelisiniz:

Access-Control-Allow-Origin: *

Bunu yaparsanız, sonuç sadece 'işe yarayabilir' değil, 'işe yarayacak' olur.

NB Eklemeniz gereken şey bir HTTP yanıt başlığıdır - böylece bunu yalnızca sizin kontrol ettiğiniz bir sunucuda yapabilirsiniz. Http://w3schools.com/XML/cd_catalog.xml dosyasını bir XMLHttpRequest(OP'nin sorusuna göre) kullanarak orijinal URL'sinden doğrudan getirmek asla mümkün olmayacak , çünkü bu kaynak (en azından 24 Nisan 2015 itibariyle) bu tür herhangi bir CORS başlığını dahil edin.

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing daha fazla bilgi verir.


0

Buna benzer problemim html kodumu kontrol ederek çözüldü. Formumda bir onclickişleyici vardı, bir yönteme gönder düğmesi. Bunun gibi: onclick="sendFalconRequestWithHeaders()". Bu yöntem de tıpkı sizinki gibi ajax'ı çağırıyor ve istediğimi yapıyor. Ancak beklendiği gibi değil, tarayıcım hiçbir şey döndürmüyordu.

Birinin çalışkanlığından öğrendim , bu işleyicide yanlış döndüm ve çözdüm. Beni bu mesaja gelmeden önce, seni bütün 3 günlük hafta sonu ve uygulama ofis yazma kodunda yarım gün geçirdim söz edelim CORS filters, jetty configdiğer jersey and embedded jettysadece bu düzeltmek için, tüm anlayış etrafında döner -. İlgili malzeme cross domain ajax requestsve standartlar şeyler. Javascript'teki basit hataların sizi aptal durumuna düşürmesi gülünçtü.

Doğrusu denedim signed.applets.codebase_principal_support = trueve yazdım isLocalHost() **if**. belki de bu yöntemin bizim tarafımızdan uygulanması gerekiyor, firefox böyle bir şey olmadığını söylüyor Şimdi git yamasını temiz bir şekilde göndermek için kodumu temizlemeliyim. O birine teşekkürler.


0

Bir tarayıcı isteği "127.0.0.1/somefile.html" yerel web sunucusuna değişmeden ulaşırken, "localhost / somefile.html" "0: 0: 0: 0: 0: 0: 0: 1 / somefile.html "IPv6 destekleniyorsa. Böylece ikincisi, bir alandan diğerine geçecek şekilde işlenebilir.


0

Alex Robinson ve bmju, çapraz kaynaklı sorunları anlamak için değerli bilgiler sağladı. İstenen GET / POST'u (örneğin bir CORS OAuth hizmet uç noktasına karşı) yapmadan önce istemci kodunuzda açık bir OPTIONS çağrısı yapmanız gerekebileceğini eklemek istedim. Tarayıcınız / kitaplığınız OPTIONS talebini otomatik olarak işleyemeyebilir. Gruber, bu sorunuzun olası cevaplarından biri.


0

Aynı sorunu yaşadım (readyState 4'tü ve durum 0'dı) , sonra bu eğiticide açıklanan farklı bir yaklaşımı izledim: https://spring.io/guides/gs/consuming-rest-jquery/

XMLHttpRequest'i hiç kullanmadı , bunun yerine jquery $ .ajax () yöntemini kullandı:

<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>

ve public / hello.js dosyası için (veya doğrudan aynı HTML koduna ekleyebilirsiniz):

$(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'nin içeride $.ajax()kullandığının farkındasın XMLHttpRequest, değil mi?
Manngo


-1

Bu sorunu yeni yaşadım çünkü 0.0.0.0sunucum olarak kullandım , olarak değiştirdim localhostve çalışıyor.


-4

Düzenleme: Bu cevabın bilgisi güncel olmadığı için lütfen Malvolio'nun aşağıdaki yorumlarını okuyun.

Etki alanları arası XMLHttpRequest'leri yapamazsınız.

Çağrı 127.0.0.1işe yarıyor çünkü test sayfanız adresinde bulunuyor 127.0.0.1ve yerel test de çalışıyor çünkü ... bu yerel bir test.

Diğer iki test başarısız olur çünkü JavaScript XMLHttpRequest aracılığıyla uzaktaki bir sunucuyla iletişim kuramaz.

Bunun yerine şunlardan birini düşünebilirsiniz:

  • XMLHttp - kendi sunucunuzdan uzaktaki XML içeriğinizi sizin için getirmesini isteyin (örneğin php betiği)
  • JavaScript'in tamamını korumak istiyorsanız, GoogleAppEngine gibi bir hizmeti kullanmaya çalışın.

umarım yardımcı olur


40
Bu çok yanlış. Sen edebilirsiniz etki alanları arası XMLHttpRequests yapmak.
Malvolio


24
- yeterince adil, ancak bir yorumun bunun için en iyi forum olup olmadığını bilmiyorum . Etki alanları arası XMLHttpRequest'lerin kesinlikle bazı güvenlik zorlukları vardır, ancak bu zorluklarla başa çıkmak için gerekli tüm araçları sunarlar. Bunun yanı sıra, web sitelerinin diğer web sitelerine kolayca hizmet sunmasına, verileri yaymak için CDN'leri kullanmasına ve kullanıcı isteklerine daha hızlı yanıt vermesine izin verir. Herhangi bir sorunuz varsa, bana mesaj atabilir veya daha iyisi, burada SO'da bir soru gönderebilir ve dikkatimi ona çekebilirsiniz.
Malvolio

2
@GabrielSprenger: Alanlar arası XMLHttpRequests sadece iyi bir fikir değil, günümüzde o kadar yaygın ki, bunları modern bir web uygulamasında YAPMAMAK (bazı HelloWorld'lerin ötesinde) saçma bir şey. Uygulamanızın kullandığı herhangi bir harici REST hizmeti, alanlar arası bir alan gerektirir XMLHttpRequest. İşte bu yüzden tüm bu CORS öğeleri eklendi.
Alexander Abakumov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.