Tuesday, March 14, 2006

JSONRequest Thoughts

This is feedback related to JSONRequest.

Specific detail comments

I'm curious why it is designed as a static method invocation and request ID vs. XMLHTTPRequest's instance-based approach. I would prefer to match XHR's instance-based approach, unless there is a good reason to avoid it. It would be good to match the XHR idiom as much as possible, since developers are familiar with it.

I also like the idea of request limiting on failure count. It would probably be good even for scenarios when it is not an attack, but the server is just having problems. No need to pound the server relentlessly.

General Problem Comments

In general, it feels too limiting, and I'm not sure the limits do much in the end to make it a viable alternative to just dynamically adding SCRIPT tags to the HTML head to load cross-domain scripts and/or JS data. With the dynamically added SCRIPTS, you get cookies sent to the domain, and have the option to get more than just a JSON object.

It is dangerous, but the point is it is possible to do it today. The only thing missing is being able to do a POST and getting a standard callback to know the script has loaded. I tried solving those things with the Dynamic Script Request (DSR) API.

Even though it can be dangerous, developers can use it today, and if it solves their problem, then they will use it. If it is possible to get browser makers to do some work in the area of cross domain script usage, I would prefer to see that effort used to strengthen the existing method and to provide the ability to specify a page-level script policy concerning cross domain scripts.

Strengthen Existing Pathway

I would like to see the following things added to to script tags, and/or have a ScriptRequest object to encapsulate the behavior (I don't really care about the names of these attributes, just what capabilities they allow):
  • method="POST"
  • data="url encoded data sent as the POST body"
  • sync="true" (to get blocking requests)
  • onload="event callback that really worked and was called when the script was loaded"
  • createScope="true" (or something that says "don't treat read the data and do the equivalent of a window.eval () on it. Instead, treat the data as specific scope or as instance object).
Maybe instead of onload, onreadystate, to allow Comet-style connections (the "Duplex" section in the JSONRequest document)?

The HTTP request headers could not be modified by the script request object (except indirectly, in the case of the cookie header). In addition, I would require that a Referer HTTP header be sent with the request. There was a comment on the WHATWG mailing list that Referer is not sent for HTTPS requests. I think something needs to be sent to indicate the calling domain and page path in the HTTP headers so that the server handling the request can make a decision on whether to allow the request.

Page Level Cross Domain Script Policy

Cross domain XML policy files on the server (like the ones used by Flash) do not seem sufficient. As far as I know, those only allow setting domain-to-domain trusts, but there could be many types of web applications on a domain (one HTML page can be a whole application). Sites can host pages from many users.

It should be possible to specify a cross domain script policy in a web page. Something that would set the permissions for scripts that come from other domains than the current domain. It could even be used for any exterior scripts that are loaded, even ones on the same domain. I'm not too particular on that, but it might be a good idea.

The policy would be specified by an HTML element, a child of HEAD. I do not care what the tag is called, but for the purposes of illustration, I'll use a META tag. But again, I do not have any special feelings about using META:

<meta name="ExternalScriptPolicy" content="dom=yes,cookie=no,request=no">

Different script capabilities can be allowed/disallowed, like whether to allow:
  • DOM access
  • Cookie access (maybe break it out by read and write)
  • Request access (whether the external script can use XMLHTTPRequest or ScriptRequest)
  • Other restrictions/privileges?
This tag could not be modified by script.

Conclusion

JSONRequest has some nice ideas, but since there is a gaping hole with SCRIPT tags anyway, I would prefer to use the browser makers time to improve the SCRIPT pathway, make it better to identify request origins, and provide page-level script security policies.

2 comments:

Zack Thom said...

How do you do a true POST?

I reviewed your docs, and there is some great information here, but you do not discuss how to do a POST without xmlHtpp.

I am interested in a remote scripting call that allowes me to send HEADERS.

James said...

Zack: Are you talking about in relation to JSONRequest, or you want something now?

If it is JSONRequest as documented, it won't allow you to set arbitrary headers.

If you want something that works right now in browsers today, I am not aware of a POST solution that allows setting headers. The only way I can think of right now would be to set up a proxy on your domain, use XMLHttpRequest to make a request to that proxy, then have that proxy forward the request to the desired target. But you won't get cookies for the final target in that scenario.

On the plus side, there is movement within the XMLHttpRequest standard to add cross-site requests to XMLHttpRequest, which would allow for this sort of thing. But that will take a while to get out into the world and have enough penetration to be useful.