title: CORS XSL with Chrome
body: <p>Short:</p>
  
  <p><strong>XSLT is applied to an XML and I want to load another XML using <code>document(http://...)</code>, 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?</strong></p>
  
  <hr>
  
  <p>Complete case:</p>
  
  <p>I first tried CORS request using html5Rocks example. So I have an html document, at <code>http://localhost/cors.html</code> containing this code:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  
  
  &lt;html&gt;
      &lt;head&gt;
          &lt;meta charset="utf-8"/&gt;
          &lt;title&gt;
  
          &lt;/title&gt;
          &lt;script&gt;
              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://cors1.localhost/cors-data.xml';
                  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);
          &lt;/script&gt;
      &lt;/head&gt;
      &lt;body&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>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"
  </code></pre>
  
  <p>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 <code>responseXml</code>), so I assume that the server is well configured (isn't it?).</p>
  
  <p>Now, I have a XML file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;?xml-stylesheet type="text/xsl" href="CORS.xsl"?&gt;
  
      &lt;cors source="http://cors1.localhost/CORS-data.xml"/&gt;
  </code></pre>
  
  <p>And the XSLT applied on it:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
      &lt;xsl:output method="html" encoding="utf-8" indent="yes"/&gt;
  
      &lt;xsl:template match="/cors"&gt;
          &lt;xsl:variable name="cors" select="document(@source)/cors"/&gt;
          &lt;p&gt;
              &lt;xsl:text&gt;CORS-data.xml (&lt;/xsl:text&gt;
              &lt;a href="{@source}"&gt;
                  &lt;xsl:value-of select="@source"/&gt;
              &lt;/a&gt;
              &lt;xsl:text&gt;): &lt;/xsl:text&gt;
              &lt;xsl:value-of select="$cors"/&gt;
          &lt;/p&gt;
      &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>So the XSLT should load an external document (<code>http://cors1.localhost/CORS-data.xml</code>) and displays its content (<code>&lt;xsl:value-of select="$cors"/&gt;</code>). It actually does it well in Firefox, but not in Chrome, where console says:</p>
  
  <p><code>Unsafe attempt to load URL http://cors1.localhost/CORS.xsl from frame with URL http://localhost/CORS.xml. Domains, protocols and ports must match.</code></p>
  
  <p>And page results in:</p>
  
  <p><code>CORS-data.xml (http://cors1.localhost/CORS-data.xml):</code></p>
  
  <p>There should be the document()-loaded XML content (a simple 'ok') after the <code>:</code> but it's void.</p>
  
  <p>I saw several subjects about this kind of problem, but they are about <code>file:///</code> protocol, not about <code>http://</code>. I can understand that <code>file:///</code> XSLT are disallowed for security reasons, but I don't get</p>
  
  <p><strong>why Chrome's CORS works with javascript's XHR but fails with XSLT's <code>document()</code> function?</strong> And how to fix that?</p>