CORS XSL with Chrome



Short:


XSLT is applied to an XML and I want to load another XML using document(http://...), from another domain than the XSL and the original XML. I added CORS headers to the server and it works on Firefox, not on Chrome. Why, and how to fix that?




Complete case:


I first tried CORS request using html5Rocks example. So I have an html document, at http://localhost/cors.html containing this code:



<!DOCTYPE html>


<html>
<head>
<meta charset="utf-8"/>
<title>

</title>
<script>
function createCORSRequest(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr)
{
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
}
else if (typeof XDomainRequest != "undefined")
{
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
}
else
{
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}

function go()
{
console.log('go!');
var url = 'http://ift.tt/1qGK03B';
var xhr = createCORSRequest('GET', url);
if (!xhr)
{
throw new Error('CORS not supported');
}
xhr.onload = function()
{
var responseText = xhr.responseText;
var responseXml = xhr.responseXML;
console.log(responseXml);
// process the response.
};
xhr.onerror = function()
{
console.log('There was an error!');
};
xhr.send();
}
document.addEventListener('DOMContentLoaded', go, false);
</script>
</head>
<body>
</body>
</html>


Works fine on firefox: the XHR object sends the CORS request, and it's well handled by both browser and server, thanks to the following server's .htaccess file:



Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Methods "OPTIONS, GET, POST"
Header set Access-Control-Allow-Headers "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control"


Now, I test it on Chrome... No problem, it works fine too ☺ In both browsers, the console displays the content of the XHR response (its responseXml), so I assume that the server is well configured (isn't it?).


Now, I have a XML file:



<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="CORS.xsl"?>

<cors source="http://ift.tt/1qf2XZb"/>


And the XSLT applied on it:



<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR">
<xsl:output method="html" encoding="utf-8" indent="yes"/>

<xsl:template match="/cors">
<xsl:variable name="cors" select="document(@source)/cors"/>
<p>
<xsl:text>CORS-data.xml (</xsl:text>
<a href="{@source}">
<xsl:value-of select="@source"/>
</a>
<xsl:text>): </xsl:text>
<xsl:value-of select="$cors"/>
</p>
</xsl:template>
</xsl:stylesheet>


So the XSLT should load an external document (http://ift.tt/1qf2XZb) and displays its content (<xsl:value-of select="$cors"/>). It actually does it well in Firefox, but not in Chrome, where console says:


Unsafe attempt to load URL http://ift.tt/1qGK03H from frame with URL http://localhost/CORS.xml. Domains, protocols and ports must match.


And page results in:


CORS-data.xml (http://ift.tt/1qf2XZb):


There should be the document()-loaded XML content (a simple 'ok') after the : but it's void.


I saw several subjects about this kind of problem, but they are about file:/// protocol, not about http://. I can understand that file:/// XSLT are disallowed for security reasons, but I don't get


why Chrome's CORS works with javascript's XHR but fails with XSLT's document() function? And how to fix that?


No comments:

Post a Comment