我正在尝试创建一个扩展来修改现有网站,并修复现有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文档的原始内容?
提前致谢。
答案 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}}