Re: [Xsltforms-support] two questions about the loading of instances
Brought to you by:
alain-couthures
From: COUTHURES A. <ala...@ag...> - 2011-02-23 08:47:57
|
Hello Michael, > A form I've written is behaving in an unexpected way; I wonder if > there is a flaw in the way XSLTForms is loading this external instance > or if there is a flaw in my expectations or my form. > > I've made a simplified version of the form and placed it at > > http://www.blackmesatech.com/2011/02/test.xhtml > > Short description: specifying an instance on another site leads either > to a cross-site scripting error (more or less expected), or to a parse > error because the browser (? or someone -- who?) is trying to parse > the external XML document as Javascript. Main question: what is > going on? > Here is my short answer ;-) The cross-domain feature in XSLTForms is experimental. It is limited to JSONP because it appears to be the unique possibility. I will present this at XML Prague 2011! > Longer description: I'm working on a form that loads a particular > external document. For reasons too complicated to go into here, the > document has more than one URI, and the system administrator has > suggested (or requested) that I load it from site X, even though my > form will be on site Y. If it matters, these are different host names > in the same second-level domain. Cross domain limitations appear if the full domain names with ports are different. > I didn't think this would work, since I expected it to raise an > immediate cross-site scripting error, but I made the change anyway so > I could transcribe the precise wording of the error message and > persuade the system administrator that his suggestion would not work > and we'll need to work something else out. To my surprise, the form > appears to be loading the document, without raising a cross-site > scripting error (at least not in Safari). But it's not initializing > the instance successfully. > > The demo test form has two instances, A and B. A is internal and is > only there to illustrate that some things do work as expected. B is > external and from a different domain (here, the form is on > www.blackmesatech.com and instance B is served from > tei2010.blackmesatech.com). > > The Safari activity window, the browser debugging tools in various > browsers, and my server logs all show that when the form requests > document B, it's appending '&callback=jsoninst' to the URI. So > instead of a request for > > http://tei2010.blackmesatech.com/data/Gorbals/gorbals-1851-status-codes.xml > > the server is receiving a request for > > http://tei2010.blackmesatech.com/data/Gorbals/gorbals-1851-status-codes.xml&callback=jsoninst > > which doesn't exist. When I first encountered this problem, the URI > in question already contained query parameters, so the > "&callback=jsoninst" at the end was just one more and the document is > served normally regardless. > > So my first question is: should the code that appends > "callback=jsoninst" check to see whether there are already query > parameters, and use "?" instead of "&" if there are not? > > For testing purposes, I've changed the relevant line in the definition > of XFInstance.prototype.construct to > > scriptelt.setAttribute("src", this.src > + ((this.src.indexOf("?") == -1) ? "?" : "&") + "callback=jsoninst"); > > The server is now receiving a request with "?callback=jsoninst" at the > end, and serving the data normally (ignoring the unexpected query > parameter). Thank you for pointing at this issue. Because it's just experimental, it hadn't been tested yet without any parameter... XSLTForms is considering every cross-domain request to be of JSONP kind... > Which leads to my main problem: the debugging tools in the browser > show that the external instance is being loaded, but they also show > the instance as having a fatal error, because it's not parseable as > Javascript. > A script element is created so it is executed immediately! > In Safari (5.0.3), the Web Inspector 'Resources' tab shows the XML > document being loaded, and clicking on the URI shows the header (yes > it's being served as application/xml) and content (looks like XML). > But the Content view also shows an error after the second line > (containing "<!DOCTYPE" ...): "SyntaxError: Parse error". The Error > console also shows line 2 of the document as raising a syntax error. > > In Firefox (3.6.13), the error console first shows a security error: > > Error: XForms Error (31): Security check failed! Trying to load > instance data from a different domain than document > Source File: http://www.blackmesatech.com/2011/02/test.xhtml > Line: 0 > Source Code: > <xf:instance id="B" resource="http://tei2010.blackmesatech.com/data/Gorbals/gorbals-1851-status-codes.xml"/> > > and then shows that the document has a syntax error on line 2, which > suggests that it was loaded anyway (I do not think I understand this, > but I have enough puzzles on my plate already). Mozilla XForms extension is intrusive: even if it shouldn't be activated, it always tries to show its own errors! > In Chrome (9.0.597.102), the error message in the error console reads > > Uncaught SyntaxError: Unexpected token< > > In Opera (11.01), the error console entry reads > > JavaScript - http://www.blackmesatech.com/2011/02/test.xhtml > Linked script compilation > Syntax error at line 2 while loading: > <!DOCTYPE codelist [ > ^ > expected expression, got '<' This is the way JSONP is working: a call to the callback function is generated by the external server with the JSON object as parameter. > Reading the source for the construct() function for instances, I am > not sure I understand what is going on, but it rather looks as if the > code is performing a simple end-run around the cross-site scripting > restrictions by pretending the external instance is Javascript and > adding a 'script' element to the document to cause the instance to be > loaded. In such a design, I would expect something somewhere to > undertake the task of doing something with the data once it's loaded. > I guess that it's the jsoninst() function that's supposed to do that. > > So perhaps it's significant that none of the debugging messages I've > added to jsoninst() ever show up in the debugging log. It looks a lot > as if jsoninst() is never being called, and I'm not entirely certain I > understand the mechanism by which it is supposed to be called. > > My second question is: ... well, I'm not sure what to ask. I'd like > to understand better what is going on here (sometimes I like being > able to avoid knowledge of the internals of tools I use, but it looks > like I need to suspend that principle here). Is this a known issue? > Does cross-site instance loading ever work? (I guess it must -- I > just don't understand how.) > > Any help anyone can give would be very welcome. There are other HTML elements than SCRIPT that have an src attribute but as far as I know, none of them allow to read their content with Javascript. > I'm running version 449 of xsltforms (which I think is what's included > in the xsltforms-beta3RC on sourceforge). The only modifications I > have made are the one indicated above and the inclusion of some > additional calls to DebugConsole.write in the construct() and > jsoninst() functions. > > ... > > p.s. Having drafted this, I've now spent some time reading a lot of > Web pages about the technique of dynamic 'script' elements and > have begun to wonder: is this intended to work only for XML > encoded as Javascript? Is the 'callback=jsoninst' a signal to the > server (a) to return JSON or Javascript, not XML or some other > format, and (b) to append a call to jsoninst() at the end of the > data? > > If so, then it's no wonder that loading an XML document doesn't > work. I wish I understood why security experts believe loading > XML documents from other sites is dangerous, but loading > executable code is safe. > Yes, browser security has big flaws to allow Web developers to use external Javascript libraries, external images and external frames passing them parameters. URL Rewriting might be a workaround: I tried adding this line in my localhost .htaccess Apache config file: RewriteRule gorbals-1851-status-codes.xml http://tei2010.blackmesatech.com/data/Gorbals/gorbals-1851-status-codes.xml [L] This way, an HTTP 302 Found code is sent back to the browser to ask for the redirection to be performed locally. Then, the corresponding new request sent by the browser is slightly different from the first one (a Range parameter is present...) and, unfortunately, tei2010.blackmesatech.com, at last, is answering with a 206 Partial Content code and a link-exception is generated... Activating the Apache proxy mechanism should be another possibility... Maybe your system administrator can change something for you in at least one of the servers config files. Thanks! -Alain |