Reputation: 492
I'm trying to access an SVG's contentDocument
(and change fill colors for specific paths, but that I don't have a problem with) via JavaScript. The SVG comes from user input. Whenever I try to access the contentDocument
I get the error:
(index):41 Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLObjectElement': Blocked a frame with origin "http://localhost" from accessing a cross-origin frame.
As you can see I'm using a local server the but results are the same when accessing the file locally. Here's my code:
document.getElementById("input-image").addEventListener("load", function () {
console.log("image loaded");
let svgDoc = this.contentDocument;
}, false);
var src = document.getElementById("file-input");
var target = document.getElementById("input-image");
var fr = new FileReader();
fr.onload = function (e) {
target.data = this.result;
};
src.addEventListener("change", function () {
fr.readAsDataURL(src.files[0]);
});
And the HTML:
<object data="" type="image/svg+xml" id="input-image" width="100%" height="100%"></object>
<input id="file-input" type="file" accept=".svg" />
And here's a jsFiddle.
I know this can be fixed by actually uploading the file to the server and then accessing it locally (as in, on the server) but is there a way to get this to work without introducting server side scripting and uploads?
Upvotes: 0
Views: 1158
Reputation: 19301
A suggestion for an alternative method of loading a local svg file into the DOM is to
iframe
object's documentConcept code
This code uses an example string instead of performing step 1.
let svgTest = function() {
let iframe = document.createElement("iframe");
document.body.appendChild(iframe); // insert it in the document, somewhere
// normally read the svg as text, but here just use an example from
// https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Getting_Started
let result = `
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
`;
// write it to the iframe and close the document
let doc = iframe.contentWindow.document;
doc.write(result)
doc.close();
// get the svgElement
let svgElement = doc.getElementsByTagName("svg")[0];
let svgRect = svgElement.getBoundingClientRect();
// set iframe size (may need adjustment)
doc.body.style.margin = "0";
iframe.width = svgRect.width;
iframe.height = svgRect.height;
}; //end of svgTest
svgTest();
Upvotes: 2