李恒道 发表于 2022-6-10 23:48:27

[油猴脚本开发指南]油猴的本质以及document的处理(五)

# Cxxjackie点评
@grant unsafeWindow并不是一句很方便的声明,他潜在造成的问题可能比你想象的多,在这一模式下很多原生的函数、对象会被油猴接管,比如setTimeout/clearTimeout、setInterval/clearInterval,在某些情况下可能造成意料之外的错误,解决方法通常是在前面加一个“unsafeWindow.”以确保得到的是原生引用。关于这个document的问题,在unsafeWindow + document-start的前提下,如果你想避免麻烦,最好在代码前加上这句:

    const document = unsafeWindow.document;
# 大总结
我们在脚本的初始化的过程中
对window进行了代理,叫做context
而context存在一个get函数
我们油猴脚本的函数的this就是这个代理过得window
而unsafewindow而是没有经过代理的window
代理的window会做各式各样的操作
例如如我们在函数内访问document
实际是访问的代理window的document
参考https://bbs.tampermonkey.net.cn/thread-2494-1-1.html
此时会触发代理window的get函数
get函数发现是document会执行对象的处理函数
此时会执行ee函数
ee函数则会在其内部执行N、M、I三个函数
N函数则对evalute进行了修改
参考https://bbs.tampermonkey.net.cn/thread-2495-1-1.html
M函数对["write", "writeln", "open", "close"]进行了修改
参考https://bbs.tampermonkey.net.cn/thread-2496-1-1.html
I函数对addEventListener和removeEventListener进行了修改
参考https://bbs.tampermonkey.net.cn/thread-2497-1-1.html
也就是说在我们油猴脚本内访问各式各样window的函数
都会触发相应的get并且有各种行为来为其进行保驾护航
而我们之所以在脚本内访问dcoument函数后使用
EventTarget.prototype.addEventListener劫持失败
是因为我们在函数内部使用了document
触发了油猴的get,然后对其addEventListener进行劫持了
而默认的addEventListener在其原型链上
document自身没有addEventListener函数
如果油猴对其document自身设置了addEventListener
则根据原型链原则不会调用原型上的addEventListener函数
所以我们EventTarget.prototype.addEventListener无效
其他属性也是同理
# 结语
撒花~

cxxjackie 发表于 2022-6-11 11:45:54

@grant unsafeWindow并不是一句很方便的声明,他潜在造成的问题可能比你想象的多,在这一模式下很多原生的函数、对象会被油猴接管,比如setTimeout/clearTimeout、setInterval/clearInterval,在某些情况下可能造成意料之外的错误,解决方法通常是在前面加一个“unsafeWindow.”以确保得到的是原生引用。关于这个document的问题,在unsafeWindow + document-start的前提下,如果你想避免麻烦,最好在代码前加上这句:
const document = unsafeWindow.document;

李恒道 发表于 2022-6-11 11:54:33

cxxjackie 发表于 2022-6-11 11:45
@grant unsafeWindow并不是一句很方便的声明,他潜在造成的问题可能比你想象的多,在这一模式下很多原生的 ...

我加上!

脚本体验师001 发表于 2022-6-11 13:59:50

...
// @grant      unsafeWindow
...

window.睾丸 = 2;
console.log(unsafeWindow.睾丸);
console.log(window.睾丸);

页面的window并不接受这俩睾丸
那么问题是
现在的睾丸到底属于谁的睾丸
如果属于window的,window又是谁,薛定谔吗?

李恒道 发表于 2022-6-11 20:31:49

脚本体验师001 发表于 2022-6-11 13:59
...
// @grant      unsafeWindow
...


属于proxy代理的window
赋值的时候触发set属性然后保存到context内

脚本体验师001 发表于 2022-6-11 20:56:35

李恒道 发表于 2022-6-11 20:31
属于proxy代理的window
赋值的时候触发set属性然后保存到context内

看平日晃晃荡荡,以为平常。扯起来又很痛
但看老大扯的明白,顿有所悟
老大威武
页: [1]
查看完整版本: [油猴脚本开发指南]油猴的本质以及document的处理(五)