开发者

XMLHttpRequest status 0 (responseText is empty)

开发者 https://www.devze.com 2023-02-10 09:48 出处:网络
Cannot get data with XMLHttpRequest (status 0 and responseText is empty): xmlhttp=new XMLHttpRequest();

Cannot get data with XMLHttpRequest (status 0 and responseText is empty):

xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET","http://www.w3schools.com/XML/cd_catalog.xml", true);
xmlhttp.onreadystatechange=function() 
{
  if(xmlhttp.readyState==4)
    alert("status " + xmlhttp.status);
}
xmlhttp.send();

It alerts "status 0".

The same situation with the localhost request (cd_catalog.xml is saved 开发者_高级运维as a local file)

xmlhttp.open("GET","http://localhost/cd_catalog.xml", true);

But with the localhost IP request

xmlhttp.open("GET","http://127.0.0.1/cd_catalog.xml", true);

and with the local file request

xmlhttp.open("GET","cd_catalog.xml", true);

everything is OK (status 200)

What can cause the problem (status=0) with the online request?

PS: Live HTTP Headers shows that everything is OK in all 4 cases:

  HTTP/1.1 200 OK
  Content-Length: 4742

PS2: Apache local web server on VMWare (host OS Win7, Guest OS Ubuntu, Network adapter – NAT). Browser – Firefox.


status is 0 when your html file containing the script is opened in the browser via the file scheme. Make sure to place the files in your server (apache or tomcat whatever) and then open it via http protocol in the browser. (i.e. http://localhost/myfile.html) This is the solution.


The cause of your problems is that you are trying to do a cross-domain call and it fails.

If you're doing localhost development you can make cross-domain calls - I do it all the time.

For Firefox, you have to enable it in your config settings

signed.applets.codebase_principal_support = true

Then add something like this to your XHR open code:

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

For IE, if I remember right, all you have to do is enable the browser's Security setting under "Miscellaneous → Access data sources across domains" to get it to work with ActiveX XHRs.

IE8 and above also added cross-domain capabilities to the native XmlHttpRequest objects, but I haven't played with those yet.


Actually make sure your button type is Button not Submit, that caused status conflict where I met recently.


If the server responds to an OPTIONS method and to GET and POST (whichever of them you're using) with a header like:

Access-Control-Allow-Origin: *

It might work OK. Seems to in FireFox 3.5 and rekonq 0.4.0. Apparently, with that header and the initial response to OPTIONS, the server is saying to the browser, "Go ahead and let this cross-domain request go through."


Consider also the request timeout:

Modern browser return readyState=4 and status=0 if too much time passes before the server response.


Add setRequestHeader("Access-Control-Allow-Origin","*") to your server response.


I had faced a similar problem. Every thing was okay, the "readystate" was 4, but the "status" was 0. It was because I was using a Apache PHP portable server and my file in which I used the "XMLHttpRequest" object was a html file. I changed the file extension to php and the problem was solved.


Open javascript console. You'll see an error message there. In my case it was CORS.


To see what the problem is, when you get the cryptic error 0 go to ... | More Tools | Developer Tools (Ctrl+Shift+I) in Chrome (on the page giving the error)

Read the red text in the log to get the true error message. If there is too much in there, right-click and Clear Console, then do your last request again.

My first problem was, I was passing in Authorization headers to my own cross-domain web service for the browser for the first time.

I already had:

Access-Control-Allow-Origin: *

But not:

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

in the response header of my web service.

After I added that, my error zero was gone from my own web server, as well as when running the index.html file locally without a web server, but was still giving errors in code pen.

Back to ... | More Tools | Developer Tools while getting the error in codepen, and there is clearly explained: codepen uses https, so I cannot make calls to http, as the security is lower.

I need to therefore host my web service on https.

Knowing how to get the true error message - priceless!


To answer the question of why http://127.0.0.1/cd_catalog.xml works while http://localhost/cd_catalog.xml doesn't: Firefox is treating 127.0.0.1 and localhost as two different domains.


Here's another case in which status === 0, specific to uploading:

If you attach a 'load' event handler to XHR.upload, as suggested by MDN (scroll down to the upload part of 'Monitoring progress'), the XHR object will have status=0 and all the other properties will be empty strings. If you attach the 'load' handler directly to the XHR object, as you would when downloading content, you should be fine (given you're not running off localhost).

However, if you want to get good data in your 'progress' event handlers, you need to attach a handler to XHR.upload, not directly to the XHR object itself.

I've only tested this so far on Chrome OSX, so I'm not sure how much of the problem here is MDN's documentation and how much is Chrome's implementation...


Alex Robinson already (and first) gives the correct answer to this issue. But to elaborate it a little more...

You must add the HTTP response header:

Access-Control-Allow-Origin: *

If you do this, the result is not just 'might work', but 'will work'.

NB What you need to add is an HTTP response header - so you can only do this on a server which you control. It will never be possible to directly fetch http://w3schools.com/XML/cd_catalog.xml from its original URL using an XMLHttpRequest (as per OP's question), because that resource does not (at least, not as of 24 Apr 2015) include any such CORS header.

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing gives more info.


My problem similar to this was solved by checking my html code. I was having an onclick handler in my form submit button to a method. like this : onclick="sendFalconRequestWithHeaders()". This method in turn calls ajax just like yours, and does what I want. But not as expected, my browser was returning nothing.

Learned From someone's hardwork, I have returned false in this handler, and solved. Let me mention that before arriving to this post, I have spent a whole 3-day weekend and a half day in office writing code implementing CORS filters, jetty config, other jersey and embedded jetty related stuff - just to fix this., revolving all my understanding around cross domain ajax requests and standards stuff. It was ridiculous how simple mistakes in javascript make you dumb.

To be true, I have tried signed.applets.codebase_principal_support = true and written isLocalHost() **if**. may be this method needs to be implemented by us, firefox says there is no such Now I have to clean my code to submit git patch cleanly. Thanks to that someone.


A browser request "127.0.0.1/somefile.html" arrives unchanged to the local webserver, while "localhost/somefile.html" may arrive as "0:0:0:0:0:0:0:1/somefile.html" if IPv6 is supported. So the latter can be processed as going from a domain to another.


Alex Robinson and bmju provided valuable information to understand cross-origin issues. I wanted to add that you may need to make an explicit OPTIONS call in your client code before making the desired GET/POST (e.g. against a CORS OAuth service endpoint). Your browser/library may not automatically handle the OPTIONS request. Gruber, this is one of the possible answers to your question.


I had the same problem (readyState was 4 and status 0), then I followed a different approach explained in this tutorial: https://spring.io/guides/gs/consuming-rest-jquery/

He didn't use XMLHttpRequest at all, instead he used jquery $.ajax() method:

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

and for the public/hello.js file (or you could insert it in the same HTML code directly):

$(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);
   });
 });


I had to add my current IP address (again) to the Atlas MongoDB whitelist and so got rid of the XMLHttpRequest status 0 error


bottle app in python:

@route('/mazer2/get', method='POST')
def GetMaze2():
    if MazeCore == None: abort(666, "MazeCore поломался :///")
    Check()
    Comm = request.body.read().decode("utf-8")
    Map = MazeCore.GetMaze2(Comm, TestToken2())
    response.headers["Access-Control-Allow-Origin"] = "*" #Here ;'-} It helped me
    return Map


I had the same problem when I tried to consume some web methods created by python in a flask environment, by XMLHttpRequest. After inspecting the firefox console, I realised that the cause of problem was Same Origin Policy, which prevents calling web methods of a different ORIGIN (An Origin consists of a 3 part tuple including: protocol, domain, and port number). For me, the solution was to use CORS, and fortunately there is a python package named flask-cors which I used and everything works fine.


I just had this issue because I used 0.0.0.0 as my server, changed it to localhost and it works.


Edit: Please read Malvolio's comments below as this answer's knowledge is outdated.

You cannot do cross-domain XMLHttpRequests.

The call to 127.0.0.1 works because your test page is located at 127.0.0.1, and the local test also works since, well... it's a local test.

The other two tests fail because JavaScript cannot communicate with a distant server through XMLHttpRequest.

You might instead consider either:

  • XMLHttp-request your own server to fetch your remote XML content for you (php script, for example)
  • Trying to use a service like GoogleAppEngine if you want to keep it full JavaScript.

Hope that helps

0

精彩评论

暂无评论...
验证码 换一张
取 消