为什么我可以在第一次尝试时从 iframe 写入 sessionStorage,但不能连续尝试? (Chrome 版本 74)

Why can I write to sessionStorage from an iframe on the first try, but not any consecutive tries? (Chrome Version 74)

此问题已出现在最新版本的 Chrome (74.0.3729.108) 中。这是本地文件系统所独有的,因为当应用程序在服务器上时,我有其他方法可以在 iframe 中加载相邻文档。

在我的应用程序中,我们已经能够通过将 iframe 写入 DOM,使用 JavaScript 从文件系统加载文档,然后将 iframe 中的文档写入 [=14] =] 到 sessionStorage。 iframe 完成加载后,我们使用 iframe 上的 onload 属性捕获它并处理将项目写入 sessionStorage.

我已将其缩小到一些基本代码,发现这仅在第一次尝试时有效,然后在第一次失败后进行任何尝试。

这是一个最小的 HTML 文档:

<!DOCTYPE html>
<html>
<head>
  <title>Chrome iFrame Tester</title>
  <script src="iframe-load.js"></script>
</head>
<body onload="OnLoad()">
  <div id="result"></div>
</body>
</html>

这里是 JavaScript:

var urls = ['file://C:/Users/afrench/Documents/Other/Misc%20Code/Chrome%20iFrame/Doc1.html', 
            'file://C:/Users/afrench/Documents/Other/Misc%20Code/Chrome%20iFrame/Doc2.html'];

HandleLoad = function () {
  'use strict';

  var data;

  try {
    data = window.sessionStorage['data'];
    delete window.sessionStorage['data'];
  } catch (ignore) {
    // something went wrong
  }

  var container = document.getElementById('container');
  window.document.body.removeChild(container);

  if (data !== null && data !== undefined) {
    var resultContainer = document.getElementById('result');
    resultContainer.innerHTML += data;
  }

  if (urls.length > 0) {
    OnLoad();
  }
}

function OnLoad() {
  var url = urls[0];

  if (url) {
    urls.splice(0, 1);

    var container = document.createElement('div');
    container.id = 'container';
    container.style.visibility = 'hidden';
    window.document.body.appendChild(container);
    container.innerHTML = '<iframe src="' + url + '" onload="HandleLoad();"></iframe>';
  }
}

在文件系统中,我们将 HTML 写入 index.html,紧挨着它的是两个最小的 HTML 文件,Doc1.htmlDoc2.html.它们的内容除了正文 div:

中的识别语句外都是相同的

邻居文档HTML:

<!DOCTYPE html>
<html>
<head>
  <title>Chrome iFrame Tester</title>
  <script>
    function OnLoad() {
      try {
        window.sessionStorage['data'] = window.document.body.innerHTML;
      } catch {
        // no luck
      }
    }
  </script>
</head>
<body onload="OnLoad()">
  <div>This is Doc 1's content!</div>
</body>
</html>

当这里是运行时,我们应该看到index.htmlresultdiv中写入的两个邻居文档的内容HTML。

当我 运行 这个最小的例子时,我可以看到内容已成功写入 sessionStorage 然后写入第一个文档的 DOM ,但下一次尝试失败.我该怎么做才能让它始终如一地工作,以及它失败的原因是什么?

我不确定是什么导致了奇怪的行为,所以希望其他人可以提供一些关于这里到底发生了什么的见解。

与此同时,这里有一个使用 window.postMessage 的替代解决方案:

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Chrome iFrame Tester</title>
  <script src="iframe-load.js"></script>
</head>
<body onload="OnLoad()">
  <div id="result"></div>
</body>
</html>

iframe-load.js

var urls = ['file://C:/Users/afrench/Documents/Other/Misc%20Code/Chrome%20iFrame/Doc1.html', 
            'file://C:/Users/afrench/Documents/Other/Misc%20Code/Chrome%20iFrame/Doc2.html'];

window.addEventListener('message', event => {
  'use strict';

  var data = event.data;

  var container = document.getElementById('container');
  window.document.body.removeChild(container);

  if (data) {
    var resultContainer = document.getElementById('result');
    resultContainer.innerHTML += data;
  }

  if (urls.length > 0) {
    OnLoad();
  }
})

function OnLoad() {
  var url = urls.shift();

  if (url) {
    var container = document.createElement('div');
    container.id = 'container';
    container.style.visibility = 'hidden';
    window.document.body.appendChild(container);
    container.innerHTML = '<iframe src="' + url + '"></iframe>';
  }
}

Doc1.html

<!DOCTYPE html>
<html>
<head>
  <title>Chrome iFrame Tester</title>
  <script>
    function OnLoad() {
      window.parent.postMessage(window.document.body.innerHTML, '*');
    }
  </script>
</head>
<body onload="OnLoad()">
  <div>This is Doc 1's content!</div>
</body>
</html>