在 PageMod (Firefox Add-on SDK) 的 HEAD 标签顶部插入脚本

Insert a script at the top of HEAD tag in PageMod (Firefox Add-on SDK)

我想在通过 page-mod 添加的 Firefox 附加组件 SDK 内容脚本中插入一个脚本。因此,当用户转到页面 XXX 时,他会得到一个包含插入脚本的页面。但是,当试图将它插入到 HEAD 的顶部时,我得到一个错误,即第一个节点子节点不是一个对象。

我用来插入 <script> 的内容脚本代码是:

script='<script>var d=new Date(2012,2,24); window.Date=function () {return d;}</script>';

var head = document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild);

这是怎么回事?

您还没有提供 Minimal, Complete, and Verifiable Example。因此,此答案仅基于您提供的代码。

关于您使用方式的问题 insertBefore():

我注意到的第一个问题是,当 insertBefore() 的第一个参数需要是 节点对象 .[=27 时,您提供了一个字符串作为第一个参数=]

但是,您声明收到的错误是“第一个节点子节点不是对象”。根据提供的代码,这与我对错误的预期不符。当我将您的代码放入 page-mod 内容脚本时,我得到的错误是:

console.error: testpagemodinsertBefore:
Object
    - _errorType = TypeError
    - message = Argument 1 of Node.insertBefore is not an object.
    - fileName = resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/loader/sandbox.js -> resource://testpagemodinsertbefore/data/contentScript.js
    - lineNumber = 26
    - stack = @resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/commonjs/sdk/loader/sandbox.js -> resource://testpagemodinsertbefore/data/contentScript.js:26:1|
    - name = TypeError

这是我期望从问题代码中得到的错误。因此,您要么没有发布产生您所述错误的代码,要么您没有准确报告您在控制台中看到的错误。以后,请准确报告您的报告。更冗长总比遗漏好。

正在插入 HTML 文本:

您的代码:

script='<script>var d=new Date(2012,2,24); window.Date=function () {return d;}</script>';

定义了您要插入到 DOM 中的一些 HTML 文本。 如果您想插入 HTML 文本而不是插入节点,一种方法是使用 insertAdjacentHTML()。您可以在代码中执行此操作的一种方法是:

head.insertAdjacentHTML('afterbegin',script);

这适用于大多数 HTML。但是,不会导致 <script> 标签的内容为 executed/evaluated。这是 for security reasons. It is much easier for an attacker to get arbitrary text inserted into the DOM than it is for them to insert actual nodes/elements. The HTML specification specifies that a tag inserted inserted as text will not be executed.

插入一个被评估和执行的<script>标签:

我们可以创建一个包含所需脚本文本的 <script> 元素,然后将该元素插入 DOM.

你的代码看起来像这样:

//Get the first <head> element
let head = document.getElementsByTagName("head")[0];

//The script text desired
let scriptText='var d=new Date(2012,2,24); window.Date=function () {return d;};';

//Add an alert for testing (\n is not needed. But, is more readable when inspecting DOM.)
scriptText = 'window.alert("In inserted script");\n' + scriptText;

//Create a <script> element
let scriptEl = document.createElement( 'script' );
//That is JavaScript
scriptEl.type = 'text/javascript'; 
//Add the script text
scriptEl.textContent = scriptText;
//Insert it as the firstChild of <head>
head.insertBefore( scriptEl, head.firstChild );

进一步阅读:

您似乎希望使用您的内容脚本与页面脚本进行交互。我建议您阅读 MDN 页面“Interacting with page scripts”。