【问题标题】:document.write() not working in userscript with Firefoxdocument.write() 在 Firefox 的用户脚本中不起作用
【发布时间】:2026-01-04 05:40:01
【问题描述】:

我有一些使用的用户脚本

var tab = window.open('', '_blank');
tab.document.write(myCustomHtml);
tab.document.close();

向用户显示输出(myCustomHtml 是我之前在代码中定义的一些有效 HTML)。自 27 版以来,它在 Firefox 中停止工作,现在我只得到一个空文档。没有任何控制台错误。

新打开的文档在用 Firefox 的控制台检查时只有这个内容

<html>
    <head></head>
    <body>
    </body>
</html>

源代码为空。

代码在 Chrome 中运行。

我需要对较新的 Firefox 版本 (27+) 和更新的 Greasemonkey (1.15) 进行任何修改吗?我没有发现任何最近向 Firefox 报告的关于此问题的错误。

这是一个测试脚本

// ==UserScript==
// @name           document.write() test
// @namespace      *.com
// @description    tests document.write()
// @include        https://*.com/questions/22651334/*
// @include        http://*.com/questions/22651334/*
// @version        0.0.1
// ==/UserScript==

var tab = window.open('', '_blank');
tab.document.write('<html><head></head><body><ul><li>a</li><li>b</li><li>c</li></ul></body></html>');
tab.document.close();

【问题讨论】:

  • document.write() 在渲染过程中会产生各种不想要的效果。最好将元素直接添加到 DOM。
  • 我知道这是一个讨厌的功能,我也知道风险,但它让我省去了很多行。考虑到我从一个空文档开始,使用“离线”数据和非常简单的布局,我宁愿保留它。
  • 我已经在 firefox 28 中使用简单的 html 标记 "&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt; &lt;ul&gt;&lt;li&gt;a&lt;/li&gt;&lt;li&gt;b&lt;/li&gt;&lt;li&gt;c&lt;/li&gt;&lt;/ul&gt; &lt;/body&gt;&lt;/html&gt;" 测试了您的脚本,并且对我有用,也许它与您尝试使用的 html 有关....等等呢你的greasemonkey中的配置?:我已经在一个纯html网页中测试了它。
  • 抱歉,现在在greasemonkey中测试...同样的问题。
  • 谢谢。我在问题中添加了一个测试脚本。

标签: javascript firefox greasemonkey userscripts


【解决方案1】:

我不确定 Greasemonkey 或 Firefox 是否已经解决了这个问题,但 window.open 从 Greasemonkey 脚本到空白页现在会触发 Same Origin Policy 违规。
同时,Page 范围、控制台范围和 Firebug 的控制台都可以正常工作。

Greasemonkey 范围给出:

SecurityError: 操作不安全

是否使用@grant none

这个,加上GM_openInTab() 的一般无用,让我怀疑这是一个 Greasemonkey 错误。我现在没有时间研究它,但是file a bug report,如果你愿意的话。

要让它在最新版本的 Firefox (28.0) 和 Greasemonkey (1.15) 上运行,我必须这样做:

  1. 告诉我的弹出窗口阻止程序(暂时)允许来自 *.com 的弹出窗口。
  2. 将弹出代码注入页面范围。
  3. 为 URL 使用明确的 about:blank
  4. 等待新窗口加载。

这是适用于最新 FF+GM 版本的完整脚本:

// ==UserScript==
// @name        document.write () test
// @description tests document.write ()
// @include     http://*.com/questions/22651334/*
// ==/UserScript==

function fireNewTab () {
    var newTab = window.open ('about:blank', '_blank');
    newTab.addEventListener (
        "load",
        function () {
            //--- Now process the popup/tab, as desired.
            var destDoc = newTab.document;
            destDoc.open ();
            destDoc.write ('<html><head></head><body><ul><li>a</li><li>b</li><li>c</li></ul></body></html>');
            destDoc.close ();
        },
        false
    );
}

addJS_Node (null, null, fireNewTab);

function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

【讨论】:

  • 谢谢,特别是功能齐全的 sn-p 替代品。我认为这是“我需要对较新的 Firefox 版本进行任何修改吗?”的结论性答案。我会为 Greasemonkey 的人写一张票。
【解决方案2】:

尝试用tab.document.body.innerHTML代替tab.document.write()tab.document.close(),也就是

var tab = window.open('', '_blank');
tab.document.body.innerHTML = '<ul><li>a</li><li>b</li><li>c</li></ul>';

(我正在使用 Firefox v24.4.0 和 Greasemonkey v1.15,这对我有用。)

我不知道此问题的根本原因,但是当我将 document.write() 包含在 try-catch 块中时,我从 alert() 收到以下错误消息。

The operation is insecure.

可能相关:Bug 663406 - document.write does not work in devtools scratchpad and console

【讨论】:

  • 那个错误(太)不相关,反正在 3 个版本前就已经解决了。
最近更新 更多