[Xsltforms-support] Content negotiation problem: HTTP "Accept" header specifies non-XML content typ
Brought to you by:
alain-couthures
From: Conal T. <con...@ve...> - 2011-07-22 06:07:53
|
I have been using XSLTForms recently, for editing XML metadata records. In our project, we have a RESTful web service (based on a Fedora repository) which uses HTTP Content Negotiation to publish different representations of a resource (i.e. using the same HTTP URL, but in response to different HTTP Accept headers). Each resource may be represented as an XML metadata record or as an XForm, depending on the content-type requested. If a browser sends a request for an HTML page, we want to return an XForm embedded in HTML, but if the browser doesn't want HTML, then we send the "raw" XML record. If the browser accepts HTML, then it receives an XForm, and the XForm itself then issues a request (to the same URL!) to retrieve the XML instance. The problem is that XSLTForms doesn't specify an HTTP Accept header, and the browser (Firefox 5 for example) sends its default Accept header, which includes "text/html", etc. Hence the instance document retrieved is not the "raw" XML representation, but rather an XForm (i.e. the XForm has loaded itself as a model instance!) I think it's a bug for XSLTForms to say that it accepts "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" (which is the default Accept header in Firefox). It seems sensible to me to set an Accept header listing "text/xml" and "application/xml", so that XSLTForms can be used with services such as ours, which use content negotiation. I found I could fix the problem by explicitly setting the Accept header in xsltforms.js, in two places (there is a case for Internet Explorer and a case for other browsers). See below: > if (window.XMLHttpRequest) { > Core.openRequest = function(method, uri, async) { > // > netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); > var req = new XMLHttpRequest(); > try { > req.open(method, Core.constructURI(uri), async); > } catch (e) { > try { > req = new > ActiveXObject("Msxml2.XMLHTTP.3.0"); > } catch (e) { > try { > req = new > ActiveXObject("Msxml2.XMLHTTP"); > } catch (e) { > throw new Error("This > browser does not support XHRs(Ajax)! \n Cause: " + (e.message || > e.description || e) + " \n Enable Javascript or ActiveX controls (on > IE) or lower security restrictions."); > } > } > req.open(method, Core.constructURI(uri), async); > } > // Added by con...@ve... so xsltforms > doesn't accept "text/html" (so that HTTP content negotiation can be used) > req.setRequestHeader("Accept", > "text/xml;q=0.5,application/xml;q=0.6,application/xhtml+xml;q=0.4"); > if (Core.isMozilla) { > req.overrideMimeType("text/xml"); > } > return req; > }; > } else if (window.ActiveXObject) { > Core.openRequest = function(method, uri, async) { > try { > req = new ActiveXObject("Msxml2.XMLHTTP.3.0"); > } catch (e) { > try { > req = new ActiveXObject("Msxml2.XMLHTTP"); > } catch (e) { > throw new Error("This browser does not > support XHRs(Ajax)! \n Cause: " + (e.message || e.description || e) + > " \n Enable Javascript or ActiveX controls (on IE) or lower security > restrictions."); > } > } > req.open(method, Core.constructURI(uri), async); > // Added by con...@ve... so xsltforms > doesn't accept "text/html" (so that HTTP content negotiation can be used) > req.setRequestHeader("Accept", > "text/xml;q=0.5,application/xml;q=0.6,application/xhtml+xml;q=0.4"); > return req; > }; > } else { > throw new Error("This browser does not support XHRs(Ajax)! \n > Enable Javascript or ActiveX controls (on IE) or lower security > restrictions."); > } -- Conal Tuohy eResearch Business Analyst Victorian eResearch Strategic Initiative +61-466324297 |