Re: Using xhr with file://

On Thu, Apr 16, 2009 at 10:10 AM, Michael A. Puls II
<shadow2531@gmail.com> wrote:
> I think file:// should be a first class citizen when it comes to xhr (local page loading local .xml file for example).
>
> However, currently, there are some interoperability problems.
>
> 1. XHR doesn't work on local pages in IE. You get "Access is denied".
>
> 2. For open("GET", "non-existent.xml"):
>
> Firefox: Throws NS_ERROR_DOM_BAD_URI and .readyState stops at 1.
>
> Safari: Doesn't throw and .readyState stops at 1.
>
> Opera: Doesn't throw and .readyState stops at 4.
>
> 3. readyState changes for found local file:
>
> Firefox: 1, 2, 3 ,4 ,1
>
> Opera: 1, 2, 3, 4
>
> Safari: 1, 2, 3, 4
>
> 4. status changes inside onreadystaechange for found local file:
> try {
>    alert(this.status);
> } catch (err) {
>    alert(err);
> }
>
> Opera: invalid state error, invalid state error, 0, 0
>
> Safari: invalid state error, 0, 0, 0
>
> Firefox: 0, 0, 0, 0, 0
>
> 5. In http, you can do if (this.readyState === 4 && this.status === 200). However, for file://, you have to do (this.readyState === 4 && (this.status === 200 || document.location.protocol === "file:") or assume this.status of 0 means "file:".
>
> It'd be cool if browsers would match each other (including IE supporting xhr for file://) and either throw an exception for file not found like Firefox does or simulate http statuses for local files (200 and 404 for example), or some combo so a page will work locally and on the server without change.

What do you think about the following?

The xhr spec could make a general recommendation for non-http
requests. It wouldn't have to mention "file:" specifically.

It could recommend something like this:

1. .readyState always makes it to 4.
2. .open() doesn't throw for "file not found" or "access denied".

3. When .readyState is 4, .status is:

404 for "file not found"
200 for "file is found and readable"
403 for "forbidden"
401 for "authorization required"
400 for "bad request" (like trying to open "c:\\file.xml" instead of
"file:///c:/file.xml" or "file://localhost/c:/file.xml")

etc.

4. .responseText would be available for 200 and .responseXML would be
if the content was successfully parsed as XML or null otherwise.

Then, you could handle specif errors like this:

var req = new XMLHttpRequest();
req.open("GET",
"file:///c:/Documents%20and%20Settings%20/user/Desktop/data.xml");
req.onreadystatechange = function() {
    if (this.readyState === 4) {
        if (this.status === 200) {
            alert(this.responseXML);
            alert(this.responseText);
        } else if (this.status === 404) {
            alert('file not found');
        } else if (this.status === 403) {
            alert('forbidden');
        } else if (this.status === 401) {
            alert('authorization required');
        } else if (this.status === 400) {
            alert("bad request");
        }
    }
}
req.send();

(alerts are just an example)

-- 
Michael

Received on Sunday, 19 April 2009 13:19:54 UTC