| ~>\t/<~ |
|
||
WhatWhyWhereDownloadInstallRunHowQuickstartHTMLXMLCustom TagsOverlaysAlternate SyntaxExamplesReferenceTagsviewhtmlctrltagneticconfigJavaScript LibsDSRJavadocWhenWhoSF Project Link |
Dynamic Script Request (DSR) APILast Modified: 2006-01-17 (change history)
ProblemSecurity warning: There are security considerations with this approach. Since script is being pulled in from other domains, there is a risk of the script deciding to do something malicious on the page. It will have full access to the DOM, and it can even make requests to the page's domain, which could result in stealing or modifying data on the server. There is an element of trust that is involved in this approach. Some level of trust is usually needed in any security measure, but right now this approach does not have any nice, automated security checks. However, for a trustworthy data service, this approach can be very useful in providing an easy way for web pages to aggregate/mash up different data services.Using On-Demand JavaScript (dynamically creating a SCRIPT tag and attaching to the HEAD) is great for loading new data or UI, since it allows accessing data and UI from other domains. However, it has the following limitations that this API tries to address: Knowing when script load is complete.There is no reliable way to know when the script load is complete. The onreadystatechange and onload events are not consistent in their behavior within and across browsers (read the comments too). This API describes an event handler to be called at the end of the script response to indicate the script has loaded.GET URL length restrictionsURLs have length restrictions. It differs between browsers, browser versions and web servers, but around 1KB seems to be a safe limit to use for URLs This can be problematic if you need to send larger amounts of data back to the server. This API uses multipart script requests to segment the original server request into manageable chunks.Terminology
API Descriptiononscriptload Event HandlerThe Web Page must define the following method:window.onscriptload = function(event) { /*web page implementation details for handling script load events go here. */ }; The event has the following properties:
The file that the Data Service sends as a response to the request should call the window.onscriptload method as the last line in the file. Here are some examples calls to the onscriptload method for a data service call that returns an ATOM XML document as a JavaScript string: OK response: window.onscriptload({ id: 'http://some.domain.com/atom.js', status: 200, statusText: 'OK', //Optional response: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>[rest of XML omitted for this example]' }); Error response: window.onscriptload({ id: 'http://some.domain.com/atom.js', status: 500, statusText: 'Missing required parameter' //Optional }); Multipart response for one request part (see the multipart request section for more information): window.onscriptload({ id: 'id3389838221', //negotiated by the web page and server status: 100, statusText: 'Continue' //Optional response: { part: 3, constantParams: 'sId=39343439&ref=4423ed334' } }); Multipart RequestsIf a request for a Data Service resource is larger than what is allowed for one HTTP GET request, then multiple SCRIPT SRC tags can be used. Only one part should be sent at a time. The Data Service should respond to the part with a "100 Continue" response before the next part is sent. The onscriptload event status should be 100, and the event.response property can contain the following properties:
Data Segmentation in Multipart URLsAn URL parameter might need to be segmented to fit in a set of multipart requests. If this is necessary, the value in the name=value pair should be segmented. The name should never be segmented. Each request would include the name and a segment of the value.So, this example: bar=ThisIsAReallyLongValuecould get segmented like this: bar=ThisIsAReAny of the constantParams that the server specifies must never be segmented. ExamplesThe following examples demonstrate calling a Data Service, http://some.domain.com/widgetProperties, that returns an JavaScript object that has two properties, a name and a final color.The Web Page uses the following onscriptload function: window.onscriptload = function(event) { switch(event.status) { case 200: alert('The name of the widget is: ' + event.response.name + ', and the final color is: ' + event.response.finalColor); break; case 100: //Add the next part of a multipart request, //being sure to use an event.response.constantParams. break; case 500: alert('There was an error: ' + event.statusText); break; default: alert('Some other status: ' + event.status + ', ' + event.statusText); } } Simple URLIf it is a simple URL that does not require a multipart request:Web Page Request (dynamically-added SCRIPT SRC tag): <script type="text/javascript" src="http://some.domain.com/widgetProperties?_dsrid=a42"></script> http://some.domain.com/widgetProperties Response: window.onscriptload({ id: 'a42', status: 200, statusText: 'OK', //Optional response: { name: 'foo', finalColor: 'blue' } }); Multipart URLBuilding on the first example, say there is a third parameter bar=ThisIsAReallyReallyReallyReallyReallyLongValue (where that value *is* very long, over the HTTP GET size limit). A set of multipart script URLs would be needed. Below is the sequence of three requests and responses:Web Page Request #1 (dynamically-added SCRIPT SRC tag): <script type="text/javascript" src="http://some.domain.com/widgetProperties?_dsrid=a42&_part=1&bar=ThisIsARe"></script> http://some.domain.com/widgetProperties Response #1: window.onscriptload({ id: 'a42', status: 100, statusText: 'Continue', //Optional response: { part: 1, constantParams: 'sId=s273485' } }); Web Page Request #2 (dynamically-added SCRIPT SRC tag): <script type="text/javascript" src="http://some.domain.com/widgetProperties?_dsrid=a42&_part=2&sId=s273485&bar=allyReallyReallyReallyRe"> </script> http://some.domain.com/widgetProperties Response #2: window.onscriptload({ id: 'a42', status: 100, statusText: 'Continue', //Optional response: { part: 2 } }); Web Page Request #3 (dynamically-added SCRIPT SRC tag): <script type="text/javascript" src="http://some.domain.com/widgetProperties?_dsrid=a42&sId=s273485&bar=allyLongValue"> </script> http://some.domain.com/widgetProperties Response #3: window.onscriptload({ id: 'a42', status: 200, statusText: 'OK', //Optional response: { name: 'foo', finalColor: 'blue' } }); Tagneto ImplementationFor web pages, Tagneto supports this API via the Dsr.send() method defined in Dsr.js. It will segment the URL into a multipart URL if it is bigger than 1KB.Outstanding implementation issues:
Possible ApplicationsOne of the guiding applications for this API is to allow web pages to import RSS or ATOM feeds directly in a web page. As an example, suppose the provider for the Tagneto blog, Blogger, supported this API by doing the following:The XML feed for the blog is at this address: http://tagneto.blogspot.com/atom.xml The DSR feed could be at the following address: http://tagneto.blogspot.com/atom.js or http://tagneto.blogspot.com/atom.onscriptload.js (to indicate it calls the onscriptload method at the end of the response) The contents of the file would be the following (for the http://tagneto.blogspot.com/atom.onscriptload.js URL): window.onscriptload({ id: 'http://tagneto.blogspot.com/atom.onscriptload.js', status: 200, statusText: 'OK', //Optional response: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>[rest of XML omitted for this example]' }); The web page that would use this file would define the window.onscriptload() method, and after that function definition either author the page with the following script tag or dynamically add it: <script type="text/javascript" src="http://tagneto.blogspot.com/atom.onscriptload.js"></script> There also may need to be agreement on the character encoding for the page. Since http://tagneto.blogspot.com/atom.xml is UTF-8 encoded, then the web page that includes this script file probably should also be UTF-8 encoded. The web page can use the DOMParser JavaScript class to convert the XML string into a DOM structure. MSIE does not support DOMParser natively, but Erik Arvidsson has created a DOMParser script for IE. This approach is used on Tagneto's home page for the "Recent Blog Entries" (with a servlet converting the XML feed to the onscriptload JavaScript format). Using this approach allows the atom.onscriptload.js file to be a static file served from a web server. It should be easy to support this format of the data along with the XML version (just make the XML a JavaScript-escaped string and wrap it with the window.onscriptload call). Since this API is importing JavaScript, it also allows the Data Service provider (Blogger in this instance) some ways to validate and track proper use of the data. The Data Service provider could provide additional script in the response that inserts a tracking image in the page. However, this sort of extra script actions need to be explicitly stated to the API users (the web page authors), and ideally discussed with them before deciding on a course of action. It seems reasonable to expect some sort of tracking by the data service if they are freely providing the data for web page authors, but open, transparent discussion and implementation is suggested. If the web page authors do not trust the Data Service provider, then the data service is useless. Open Issues
Change History2006-01-17: Added more information to the "Possible Applications" section on how a web page can convert the XML string into a DOM structure. Fixed spelling errors.2006-01-15: Made substantial changes to the API. Decided to go with a reserved global callback handler, onscriptload, to simplify things. Other browser events and the XMLHttpRequest object were used to guide the format and names of the methods and parameters. Here is the old version of the API, for historical reference. 2005-12-30: Made _error optional. If not sent, server can throw a JavaScript exception for the response. Changed SvrScript references to Dsr references. 2005-11-22: Initial version. |