XSLT in Chrome extension: Unsafe attempt to load URL

11,299

Here is a workaround I'm currently using:

function loadXMLtext(url)
{
  xhttp = new XMLHttpRequest();
  xhttp.open("GET", url, false);
  xhttp.send();
  if(xhttp.responseXML == undefined) throw "XHR failed for " + url;
  return xhttp.responseXML;
}
function transformxml()
{
  var xml = loadXMLtext(document.location.href);
  var xsl = loadXMLtext(chrome.extension.getURL("message.xsl"));
  var xsltPrs = new XSLTProcessor();
  xsltPrs.importStylesheet(xsl);
  var result = xsltPrs.transformToFragment(xml, document);
  var xmlsrv = new XMLSerializer();
  var plaintext = xmlsrv.serializeToString(result);
  document.documentElement.innerHTML = plaintext;
}
transformxml();
Share:
11,299

Related videos on Youtube

Stan
Author by

Stan

I'm interested in a wide range of programming technologies, developing web-services, server-side software and frontends, Windows clients, Android apps, browser extensions, and other tools which all together form an exceptional mix for innovative products. One of the recent projects was a web-service providing a Flash bridge for iOS devices.

Updated on June 18, 2022

Comments

  • Stan
    Stan 11 months

    I'm writing a Chrome extension which should apply XSLT transform to certain XML documents on the fly. Just for testing I use the following XML and XSL files:

    XML:

    <?xml version="1.0" encoding="utf-8" ?>
    <WebServiceMessage>
     <status>timeout</status>
     <message>Nameserver%2520not%2520registered.</message>
     <stepName>Finish</stepName>
     <stepNumber>11</stepNumber>
     <maxStepNumber>11</maxStepNumber>
     <percent>100</percent>
     <session>2fc0f139b88a800151e5f21b9d747919</session>
    </WebServiceMessage>
    

    XSL:

    <?xml version="1.0" ?>
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="/">
        <html><head></head>
        <body>
          <xsl:apply-templates/>
        </body>
        </html>
      </xsl:template>
      <xsl:template match="*">
        <xsl:for-each select="*">
          <p><b><xsl:value-of select ="name(.)"/></b>:
          <span><xsl:attribute name="id"><xsl:value-of select ="name(.)"/></xsl:attribute><xsl:value-of select="."/></span></p>
        </xsl:for-each>
      </xsl:template>
    </xsl:stylesheet>
    

    The tranfromation works normally if it's linked inside a test XML file itself, that is via:

    <?xml-stylesheet type="text/xsl" href="message.xsl"?>
    

    The extension should inject the same xsl link into XML-files.

    manifest.json:

    {
      "permissions": ["tabs", "<all_urls>"],
      "content_scripts":
      [
        {
          "matches": ["<all_urls>"],
          "js" : ["contentscript.js"]
        }
      ],
      "web_accessible_resources":
      [
        "message.xsl"
      ],
      "manifest_version": 2
    }
    

    contentscript.js:

    (function()
    {
      if(document.xmlVersion != null)
      {
         var e = document.createProcessingInstruction(
                   "xml-stylesheet",
                   "type='text/xsl' href='" + chrome.extension.getURL("message.xsl") + "'");
         document.insertBefore(e, document.firstChild);
      }
    })();
    

    The problem

    Chrome outputs the following error into console:

    Unsafe attempt to load URL chrome-extension://ladfinoepkgipbeooknnklpakoknohjh/message.xsl from frame with URL http://localhost/out.xml. Domains, protocols and ports must match.

    How to fix this? I saw some reports on the Internet related to similar errors, which seems like a bug in Chrome.

    I placed the xsl-file on the web-server as well, and changed styleheet link to the web-server. Still the same error:

    Unsafe attempt to load URL http://localhost/message.xsl from frame with URL http://localhost/out.xml. Domains, protocols and ports must match.

    Apparently domains, protocols, and ports do match.

  • Stan
    Stan over 10 years
    Thanks for the answer. Some thoughts. 1) Extensions' permissions in manifest must override policies for external sites - otherwise, entire concept of extensions permissions is useless (such thing as <all_urls> etc. would be void, and might not exist at all). 2) I mentioned that even if XSL is hosted on the same domain, the error remains. Also, I can't agree about moving processing into background page - this brings too much useless overheads, and again voids existence of content scripts, which are very useful tool for "in page" processing, and it should be used when appropriate.
  • jjperezaguinaga
    jjperezaguinaga over 10 years
    You are right, just loaded knockoutjs through ajax in a content script (and I'm not even asking for permission to http://knockoutjs.com/ in my manifest). Isn't the permissions and CSP for your extension, not the webpage's? The same domain is localhost, so I'm not sure about it, try playing with your /etc/hosts and change 127.0.0.1 to a domain you wanna test. And with the new events pages it's not an overhead at all, although the API is still in dev.
  • Stan
    Stan over 10 years
    Changing localhost and local IPs to a faked domain from hosts does not help.

Related