- From: Kris Zyp <kris@sitepen.com>
- Date: Fri, 11 Feb 2011 06:48:26 -0700
- To: WebApps WG <public-webapps@w3.org>
Increasingly, web applications are centered around JSON-based content, and utilize JavaScript to render JSON to HTML. Such applications (sometimes called single page applications) frequently employ changes to the hash portion of the current URL to provide back/forward navigation and bookmarkability. However, this is largely viewed as an awkward hack, and is notoriously problematic for search engines (Google has a hash to query string conversion convention, which is also highly inelegant). We need support for first class navigation of JSON documents, while still leveraging HTML rendering technology. While current methods are ugly, navigating the web via JSON documents certainly does need not to be at odds with the standard web/URL and RESTful navigation. Navigation could be visible with plain URLs to browsers and other user agents (like search engines). Below is a proposed approach to enable first class JSON document navigation while the leveraging the current web platform. Proposal When a HTML enabled user agent/web browser navigates to a resource and the server returns a response with a Content-Type of application/json and a Link header [1] indicating a link relation of "html-renderer-script", the browser should load the target of the link relation as a script in the current JavaScript context. Multiple link relations may be included, and the target scripts should be executed in the order of the headers. The browser should construct the standard HTML DOM structure as it would normally do for a blank page or a page with simple text on it. Once the DOM has been instantiated, the referenced script(s) should execute. After the JSON document has finished downloading, the JSON document should be parsed (as with JSON.parse) and an oncontentload event should fire. The event object must contain a "content" property that references the parsed JSON value/object. An example response might look like: HTTP/1.1 200 OK Content-Type: application/json Link: /render.js; rel="html-renderer-script" {"id":1, "name":"example"} The standard DOM/JS environment would be created, the render.js script would be executed (which could be responsible for generating the appropriate DOM elements to render the data and for user interaction), and the "contentload" event would fire with the parsed object assigned to the "content" property of the event property. A simple example of a renderer script that could used in conjunction with the example response above: render.js: oncontentload = function(event){ // called for each new JSON doc, render the JSON as HTML var content = event.content; document.body.innerHTML = 'Identity: ' + content.id + ' Name: ' + content.name + '<a href="' + (content.id + 1) + '">Next</a>'; // include a navigable link }; Note that when browsers receive a response with a Content-Type of application/json, most currently either download with a save dialog or render it in <pre> element. Browsers can still default to rendering the JSON in <pre> tag, although the loaded scripts would normally alter the DOM to provide a custom rendering of the JSON. When the current page has been loaded via a JSON document, and the browser navigates to a new URL (whether by back button, forward button, typing in URL bar, bookmark, clicking on a hyperlink, or window.location being assigned), the target resource will be downloaded by the browser. If the response is also application/json and has the same link relation(s) for "html-renderer-script" as the first document, the DOM/global object will not be reloaded, but will persist after the JSON document is loaded. In this case, after the JSON document is fully downloaded, another oncontentload event will fire, with the new parsed JSON as the "content" property. Every time the browser navigates to and loads a new JSON document (with the same renderer scripts) the the oncontentload event will fire, but the global/DOM environment will remain in place. The headers from the JSON document contentload event should be available via the event.getResponseHeader(headerName) function and the event.getAllResponseHeaders() function, which act the same as the corresponding functions on XMLHttpRequest. Browsers that support loading of scripts in response to "html-renderer-script" for "application/json" should indicate their support for this capability by including application/json in their request Accept header. Browsers may also fire oncontentprogress events in addition to oncontentload events if they support progressive loading and parsing of JSON. The oncontentprogress event should only be fired if the top level of the JSON document is an array. When an oncontentprogress event fires, the "content" may be a partial array; containing a subset of the full document array that will be provided in the final oncontentload event. Web application authors could leverage browser support for these links and API to build applications based on JSON content with full JavaScript-based rendering. The JSON data providers could also include links (via Link headers) to schemas to inform non-JavaScript user agents (like search engines) on how to find hyperlinks in the JSON data and navigate them. JSON Schema [2] provides full support for describing links and their relations in target JSON data, which can be interpreted and navigated without JavaScript (but this is beyond the scope of this proposal). This would mean that JSON represented resources could be custom rendered, fully integrated into a browser's native navigation, and even completely crawlable and searchable. Future enhancements could include browser support for schema-driven default renderings or JSON style sheets, but this proposal provides a minimal mechanism that enables an entire class of applications to be properly URL driven building on existing technology. [1] http://tools.ietf.org/html/rfc5988 [2] http://tools.ietf.org/html/draft-zyp-json-schema-03 Thanks, Kris
Received on Friday, 11 February 2011 13:48:58 UTC