从文件输入访问.SVG文件的contentDocument - Chrome上的跨框架问题

时间:2016-11-15 22:38:25

标签: javascript google-chrome svg

我尝试通过JavaScript访问SVG contentDocument(并更改特定路径的填充颜色,但我没有遇到任何问题)。 SVG来自用户输入。每当我尝试访问contentDocument时,我都会收到错误:

  

(index):41未捕获的DOMException:无法读取' contentDocument'   来自' HTMLObjectElement'的属性:阻止具有原点的帧   " http://localhost"从访问跨源框架。

正如您所看到的,我使用的是本地服务器,但在本地访问文件时结果相同。这是我的代码:

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]);
});

HTML:

<object data="" type="image/svg+xml" id="input-image" width="100%" height="100%"></object>
<input id="file-input" type="file" accept=".svg" />

这里是jsFiddle

我知道这可以通过实际将文件上传到服务器然后在本地访问它来解决(例如,在服务器上)但是有没有办法让它在没有引入服务器端脚本和上传的情况下工作?

1 个答案:

答案 0 :(得分:1)

关于将本地svg文件加载到DOM的替代方法的建议是

  1. 选择后将文件读为文本(我们假设它是ASCII或utf-8编码)。
  2. 将内容写入iframe对象的文档
  3. 从iframe中获取svgElement。
  4. 概念代码

    此代码使用示例字符串,而不是执行步骤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();