XMLHttpRequest
2Since 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.
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.
Don't forget onprogress.
Matt, yeah, something like followRedirects = true|false
might be worth adding. Daniel, yes, I covered that in my post.
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.
Grégoire, in that case you would simply use the new XMLHttpRequest()
constructor and not the new XMLHttpRequest(uri)
one.
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.
Perhaps I'm just being greedy, but the addition of a responseHTML attribute would be grand.
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?
I don't like the implicit send()
either.
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.
Dustin, working cache control is already specified in version 1.
Nick, the plan is that responseXML
will also work for text/html
responses.
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...
open
is rendundant.
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.
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
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.
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?
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:)
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.
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.
With "DOM-0 event support", I of course meant "DOM-2 event support".