【问题标题】:Accessing .SVG file's contentDocument from file input - cross frame issue on Chrome从文件输入访问 .SVG 文件的 contentDocument - Chrome 上的跨框架问题
【发布时间】:2017-03-29 23:50:11
【问题描述】:

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

(index):41 Uncaught 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。

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

【问题讨论】:

  • ... 并且发布的代码已经过测试,可以在窗口加载后在 IE(11) 和 Firefox 中正常工作。使用file:// 和http://localhost/ 访问。
  • 是的,这就是我用谷歌浏览器标记它的原因,我想我应该在正文中提到这一点,而不仅仅是标题。我知道这是 Chrome 的问题,IIRC Chrome 对跨帧数据特别敏感。问题是,我正在为自己编写这个工具,而且我是 Chrome 用户,所以我非常希望它能够在 Chrome 中工作。

标签: javascript google-chrome svg


【解决方案1】:

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

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

概念代码

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

【讨论】:

    猜你喜欢
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 2021-11-22
    相关资源
    最近更新 更多