Anne van Kesteren

XMLHttpRequest 2

Since the first version of XMLHttpRequest is now more or less stable (last XMLHttpRequest draft published three days ago) I have been thinking a little bit about what type of enhancements we can make for XMLHttpRequest version 2. Here is one thing I have been thinking about:

// start "script block"
var r = new XMLHttpRequest(uri);
// uri argument causes implicit invocation of r.open("GET", uri)
r.setRequestHeader("Accept", "text/html")
r.onload = function() { … }
r.onerror = function() { … }
r.onabort = function() { … }
// end "script block" causes implicit invocation of r.send()

This is similar to how new Audio(uri) works in HTML5 and I think it is rather elegant. I think some browser extensions such as overrideMimeType to set the MIME type and responseBody to get a byte array of the response will also be added and maybe a way to better determine what exactly made the request fail. We will also be looking into integrating it with the Progress Events draft so you can track uploading and downloading of data more accurately. Finally, in combination with the Enabling Read Access for Web Resources draft we can allow cross domain requests as I mentioned earlier.

Comments

  1. Another thing I would love is the ability to capture a redirect.

    Currently, all XMLHttpRequest requests will silently follow a redirect, and the final state will reflect the page that the request redirected to.

    Even if it's as simple as adding a boolean flag to indicate whether or not the request redirected, or the ability to specify before load whether or not to silently follow redirects.

    Posted by Matt Pennig at

  2. Don't forget onprogress.

    Posted by Daniel Glazman at

  3. Matt, yeah, something like followRedirects = true|false might be worth adding. Daniel, yes, I covered that in my post.

    Posted by Anne van Kesteren at

  4. I'm not sure that the automatic r.send() at the end of the block is a good idea. What if you don't want to send the request for some reasons ? (like you test something with a "if" and you only send the request if it is true)

    Since this is not explicit, people won't expect an action to be made.

    Posted by Grégoire Cachet at

  5. Grégoire, in that case you would simply use the new XMLHttpRequest() constructor and not the new XMLHttpRequest(uri) one.

    Posted by Anne van Kesteren at

  6. The implicit call to open() is intuitive enough, but the implicit call to send() isn't. Just because the script block ends doesn't mean the author wants to execute anything. What if the r object is accessed in another script block?

    Oh, and for version 2 of XHR, I'd give my support to giving the stupid object a new name. HttpRequest please? It's not just about XML, after all.

    Posted by Asbjørn Ulsberg at

  7. Perhaps I'm just being greedy, but the addition of a responseHTML attribute would be grand.

    Posted by Nick Lange at

  8. I agree with the other commenters about the implicit r.send(). What if the new XmlHttpRequest() is created in a factory method that sets some basic parameters and returns the XmlHttpRequest object for use elsewhere?

    As for different constructors having different send() behavior, that doesn't seem particularly intuitive either. Don't we want the newer specs to have fewer gotchas?

    Posted by dnl2ba at

  9. I don't like the implicit send() either.

    Posted by Dean Edwards at

  10. The thing I'm missing is the ability to instruct my browser to not use the browser cache. Modifying the URL to be unique is wrong, and doesn't always work.

    Give me working cache control.

    Posted by Dustin at

  11. Dustin, working cache control is already specified in version 1.

    Posted by Anne van Kesteren at

  12. Nick, the plan is that responseXML will also work for text/html responses.

    Posted by Anne van Kesteren at

  13. Here's some;

    Depreciate synchronous requests - they are only viable over a network with 100% end-to-end availability (which is an impossibility) - meanwhile here's what happens on shakier networks: here's why - should never have been part of the API, at least not while Javascript is able to block the whole browser. Blame here: This History of XMLHTTP.

    Also require that HTTP headers be available during readyState 3 ("downloading") - implicit is readyState 3 means you've got the response headers but not the complete body. One use case this would enable: with Content-Length available you'd be able to do accurate download progress indication. FF supports this, IE did at some point (with early versions) then withdrew it again for some reason (now there are no headers available in ready state 3 in IE).

    Also, again readyState 3, allow users to define how often it should be "fired" - if I remember right FF fires a readyState change 3 for (something like) every 8K it downloads but that's hard coded somewhere.

    Another - define clearly behavior when setting headers like accept-language when you call multiple times - if I remember right IE appends values while FF overwrites (or vice versa).

    And caching behavior / control needs defining... For starters IE caches by default unless the server says otherwise while FF discards by default, if I remember right. Also what's the security boundary here - what can / cannot be controlled in Javascript?

    Actually got a bunch more of this lodged in my head, for when I can remember. May be back later...

    Posted by Harry Fuecks at

  14. Posted by Masklinn at

  15. It's not immediately obvious what HTTP status codes r.onload/abort/error correspond to, and there's no similar API on the backends (and will there be an on* for every HTTP status code?). On the backends you still explicitly use HTTP status.

    Posted by Vetle at

  16. Correction to earlier - the LOADING state in FF get's fired every 4k. Would be nice to have control over this.

    Some more...

    Timeouts: API support for timing out a request after X milliseconds

    Allow HTTP (Basic/ Digest) authentication to be handled entirely in Javascript - no dialogs presented to user (probably some security issues I'm missing here but...)

    Charset control - what's the default behaviour (actually this seems to be defined in 1.0 spec now I look)? How to influence / override it / force conversions?

    Support for multipart/x-mixed-replace (server "push") a requirement

    Posted by Harry Fuecks at

  17. Harry: synchronous requests aren't bad. A locking GUI is a browser-issue, not something that is an inevitable result of using synchronous requests. Firefox fixed it in Gran Paradiso, Opera doesn't have the issue so surely other browservendors can fix it too. Shaky implementations should not be an argument for omitting useful functionality.

    Posted by Tino Zijdel at

  18. Any reason why you suggest Dom Level 0-style events instead of

    var r = new XMLHttpRequest(uri)
    r.addEventListener('load',function(){});
    r.addEventListener('error',function(){});
    r.addEventListener('complete',function(){});

    Is one syntax preferable to the other?

    Posted by Ryan Cannon at

  19. I'd like to see an event object returned on events. That way you don't need to hardcode the name of the request object variable into other functions.

    var r = new XMLHttpRequest(uri);
    r.onload = function(e) { var xhr = e.getSource();}
    r.onerror = function(e) { var xhr = e.getSource(); }
    r.onabort = function(e) { var xhr = e.getSource(); }
    

    And, Ryan's suggestion about DOM-0 events is also nice:)

    Posted by Marcos Caceres at

  20. Ryan, both will be available, of course. What you call DOM-0 is what I call convenient when you only need a single listener for an event.

    Posted by Anne van Kesteren at

  21. XMLHttpRequest.responseObject would be a nice addition. This would be a JavaScript object. I think responseJSON would be wrong, since the XMLHttpRequest object hypothetically can be used in other environments and languages than JavaScript. The responseObject property would contain a deserialized representation of the responseText, if the response Content-Type matches a typical JavaScript MIME type, like text/javascript, application/ecmascript, etc.

    Perhaps we should define a getResponse() method instead, to allow for easier extension points? One could then pass parameters to get the type of response you're interested in, or this could be controlled entirely by the MIME type returned by the server.

    I'd also like DOM-0 event support and an event argument passed to the event handlers. An overloaded constructor with lots of optional parameters also sounds like a good idea.

    When it comes to HTTP authentication, it should be possible to pass on the entire current HTTP context to the server, without the script actually doing anything with it. The WWW-Authenticate header, the Cookie and such should all be passed on to the server through the XMLHttpRequest object by setting a property like transmitHttpContext or something. If the resource requested by XMLHttpRequest isn't authenticated, it should be possible to handle this with an event or something similar in the script. It should at least allow the user to authenticate through the browser's own mechanisms so that the resource can be retreived.

    Posted by Asbjørn Ulsberg at

  22. With "DOM-0 event support", I of course meant "DOM-2 event support".

    Posted by Asbjørn Ulsberg at