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
3 Answers
Reset to default 1Here 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.