最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - XSLT in Chrome extension: Unsafe attempt to load URL - Stack Overflow

programmeradmin2浏览0评论

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="">
  <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.

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/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.

Share Improve this question edited Jan 5, 2013 at 20:18 Stan asked Jan 5, 2013 at 13:17 StanStan 8,76810 gold badges62 silver badges105 bronze badges 4
  • I guess it is a security feature of chrome. – Sudarshan Commented Jan 5, 2013 at 14:15
  • I used this code without any problem, maybe it's only when you update the window.document that it does it: var documentString = document.firstChild.innerHTML; var docu = new DOMParser().parseFromString('<xml>'+documentString+'</xml>', application/xml"); var e = docu.createProcessingInstruction("xml-stylesheet", "type='text/xsl' href='" + chrome.extension.getURL("message.xsl") + "'"); docu.insertBefore(e, docu.firstChild); – jjperezaguinaga Commented Jan 6, 2013 at 18:12
  • @jjperezaguinaga You have created a new document instead of existing one. In a sense, this is the same as a workaround I posted below. – Stan Commented Jan 6, 2013 at 18:38
  • Yeah. How that has been working so far for you? – jjperezaguinaga Commented Jan 6, 2013 at 20:18
Add a ment  | 

3 Answers 3

Reset to default 1

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();

You are asking a webpage to process a resource outside its domain. You can try to "trick" the browser through localhost, but this is the same as asking facebook to execute a script from google. This is a Same Origin policy error and to solve it just move the processing from the content script to a background/event page. You will need to pass the result after processing, but that's the correct approach.

Another reason why most processing should be done in a background/event page is in order to optimize your extension, otherwise you are just using the current window engine, and if it blocks, so it does the tab for the user.

You can do this locally using Chrome's mand line flags.

The specific flag is --allow-file-access-from-files

On OS X: from Terminal.app run /Applications/Google\ Chrome.app/contents/MacOS/Google\ Chrome --allow-file-access-from-files

On Windows: from the mand prompt run C:\Users\USERNAME\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files (replacing USERNAME with your username)

Note: You will probably have to quit Chrome if it is currently running otherwise session. make sure about this.

发布评论

评论列表(0)

  1. 暂无评论