使用document_start在使用Chrome扩展程序加载之前修改文档html

时间:2012-03-14 07:40:01

标签: javascript google-chrome-extension

我正在尝试创建一个扩展来修改现有网站,并修复现有javascript中的错误。在加载之前对文档的文本内容进行简单替换将修复错误 - 特别是标题中的标记中的硬编码值 - 以及我的第一次尝试(从日期值中删除时间戳)是这样的:

document.documentElement.innerHTML = document.documentElement.innerHTML.replace(/("date_of_birth": new Date\("[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4}) \d{2}:\d{2}:\d{2} GMT/g, "$1");

例如,"date_of_birth": new Date("Tue, 30 Oct 1984 00:01:00 GMT")的任何实例都会变为"date_of_birth": new Date("Tue, 30 Oct 1984")

问题是我所知道的访问文档HTML内容的唯一方法是document.documentElement.innerHTML。在document_start中运行此操作失败,因为尚未加载DOM,因此documentElement.innerHTML是一个空字符串。在DOM加载之后运行上面的代码将太晚,因为初始化脚本已经运行,并且在那时修改文档的html会重新加载这些脚本,从而在脚本密集的页面中造成各种破坏。

在加载DOM之前,我不能简单地附加到documentElement,这是搜索解决方案时最常见的建议。这需要在加载和运行之前修改现有脚本。

在加载HTML文档之前,有没有办法访问和预处理HTML文档的原始内容?

提前致谢。

1 个答案:

答案 0 :(得分:4)

<script>执行之前无法“编辑”</script>的内容:遇到结束(function(global) { var _Date = global.Date; /* Store original Date object */ var overwriteafterXmatches = 1; /* Overwrite after X matches*/ function date(year, month, day, hour, minute, second, millisecond) { var tmp = /^([A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4}) \d{2}:\d{2}:\d{2} GMT$/.exec(year); switch(arguments.length) { case 0: return new _Date(); case 1: if (tmp) { /* If match */ tmp = new _Date(match[1]); if (--overwriteAfterXmatches <= 0) { /* Set the original Date object*/ global.Date = _Date; } } return new _Date(year); case 2: return new _Date(year, month); case 3: return new _Date(year, month, day); case 4: return new _Date(year, month, day, hour); case 5: return new _Date(year, month, day, hour, minute); case 6: return new _Date(year, month, day, hour, minute, second); default: return new _Date(year, month, day, hour, minute, second, millisecond); } } /* Overwrite global Date object*/ global.Date = date; })(window); 标记后,会立即评估内容。

可以使用间接方法而不是修改代码本身:覆盖全局Date对象,可以使用以下代码完成:

contentscript.js

<script>

内容脚本在isolated environment中运行。这意味着您无法直接修改全局属性。要使代码在Content script中运行,您必须以这种方式注入var code = "\ (function(global) {\ var _Date = global.Date; /* Store original date object*/\ var overwriteafterXmatches = 1; /* Overwrite after X matches*/\ function date(year, month, day, hour, minute, second, millisecond) {\ var tmp = /^([A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4}) \d{2}:\d{2}:\d{2} GMT$/.exec(year);\ switch(arguments.length) {\ case 0:\ return new _Date();\ case 1:\ if (tmp) { /* If match */\ tmp = new _Date(match[1]);\ if (--overwriteAfterXmatches <= 0) {\ /* Set the original Date object*/\ global.Date = _Date;\ }\ }\ return new _Date(year);\ case 2:\ return new _Date(year, month);\ case 3:\ return new _Date(year, month, day);\ case 4:\ return new _Date(year, month, day, hour);\ case 5:\ return new _Date(year, month, day, hour, minute);\ case 6:\ return new _Date(year, month, day, hour, minute, second);\ default:\ return new _Date(year, month, day, hour, minute, second, millisecond);\ }\ }\ /* Overwrite global Date object*/\ global.Date = date;\ })(window);\ "; var script = document.createElement('script'); script.appendChild(document.createTextNode(code)); (document.head||document.documentElement).appendChild(script); script.parentNode.removeChild(script); 标记:

manifest.json

<all_urls>

以下是manifest.json文件的示例。将{ "name": "Test", "version": "1.0", "content_scripts": [ { "matches": ["<all_urls>"], "js": ["contentscript.js"], "run_at": "document_start" } ], "permissions": ["<all_urls>"] } 替换为更具体的match pattern

{{1}}