从文件输入中访问.svg文件's contentDocument - Chrome上的跨框架问题

Accessing .SVG file's contentDocument from file input - cross frame issue on Chrome

本文关键字:文件 Chrome 问题 框架 contentDocument 访问 输入 svg      更新时间:2023-09-26

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

(index):41 Uncaught DOMException: Failed to read 'contentDocument'property from ' htmllobjectelement ':阻塞了一个有origin的框架"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

我知道这可以通过实际上将文件上传到服务器,然后在本地访问它(如在服务器上)来修复,但是有没有一种方法可以在不引入服务器端脚本和上传的情况下使其工作?

将本地svg文件加载到DOM的另一种方法是:

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

概念代码/strong>

这段代码使用了一个示例字符串而不是执行步骤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();