上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

关于grant none/unsafeWindow之疑惑

[复制链接]
  • TA的每日心情
    难过
    17 小时前
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    13

    主题

    71

    回帖

    100

    积分

    荣誉开发者

    积分
    100

    荣誉开发者油中2周年油中3周年新人报道挑战者 lv2喜迎中秋

    发表于 2025-8-14 13:50:01 | 显示全部楼层 | 阅读模式
    悬赏10油猫币已解决

    看官方教程

    grant介绍,none与unsafeWindow

    沙盒机制的前世今生

    或者网上搜索教程或者问AI

    都说的头头是道,感觉似乎懂了,但一测试就懵逼了😳

    这里汇总教程的大意是:

    1. grant none 是脚本直接运行在前端页面中,此时可以访问页面中的原有变量,可以访问页面元素,但不能访问GM_*系列函数

    2. 默认(即无none和unsafeWindow的情况下),运行在沙盒中,无法访问页面中的原有变量,可以访问页面元素,可以访问GM_*系列函数

    3. grant unsafeWindow是运行在沙盒中,可以通过unsafeWindow访问页面中的原有变量,可以访问页面元素,可以访问GM_*系列函数

    总结如下:
    image.png

    但,我测试下来,却完全不是这样,什么默认,grant none,grant unsafeWindow效果完全一样。

    以下是测试代码:

    网页代码如下

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <title></title>
        </head>
    
        <body>
            <div id="dom1">dom 1</div>
            <button id="closePage">关闭页面</button>
            <script>
                var a=1;
                window.b=2;
                c=3;
                let d=4;
                const e = 5;
            </script>
        </body>
    </html>

    在线地址 https://wilson.lovestoblog.com/demo/scriptcat_demo.html

    油猴代码如下

    // ==UserScript==
    // @name         Demo
    // @namespace    https://bbs.tampermonkey.net.cn/
    // @version      0.1.0
    // @description  try to take over the world!
    // @author       You
    // @match        *://*/*
    // ==/UserScript==
    
    console.log('---> demoooooooooooooooooooo start <---')
    console.log('变量', {a,b,c,d,e});
    console.log('dom', document.querySelector('#dom1'));
    document.querySelector('#closePage').addEventListener('click', ()=>window.close());
    console.log('---> demoooooooooooooooooooo end <---')

    注意,这里div id 是 dom1 不是demo1,别看错了!

    浏览器打印结果(无论默认,grant none,grant unsafeWindow效果完全一样)
    image.png

    所以,我的疑惑是:我理解错了吗?还是测试错了?还是教程错了? 懵逼。。。

    最佳答案

    查看完整内容

    [md]教程有一些问题,你来听我狡辩一下: 目前的沙盒是一个半沙盒的情况,教程中描述的是全沙盒的情况,教程是我最开始编写的,可能有些问题。 目前的半沙盒是: 沙盒中可以访问外面的变量(除了一些特殊定义的以外:例如`define`、`export`),但是外面的变量不能到沙盒里面来,如果你在沙盒内定义`window.b=100`,在页面上访问b还是为2。 脚本猫最近的一次重构沙盒,里面有很多细节,有兴趣可以看看 https://github.com/scri ...
    无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人。
  • TA的每日心情
    郁闷
    2025-7-22 00:22
  • 签到天数: 221 天

    [LV.7]常住居民III

    311

    主题

    4909

    回帖

    4576

    积分

    管理员

    积分
    4576

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2025-8-14 13:50:02 | 显示全部楼层

    教程有一些问题,你来听我狡辩一下:

    目前的沙盒是一个半沙盒的情况,教程中描述的是全沙盒的情况,教程是我最开始编写的,可能有些问题。

    目前的半沙盒是: 沙盒中可以访问外面的变量(除了一些特殊定义的以外:例如defineexport),但是外面的变量不能到沙盒里面来,如果你在沙盒内定义window.b=100,在页面上访问b还是为2。

    脚本猫最近的一次重构沙盒,里面有很多细节,有兴趣可以看看
    https://github.com/scriptscat/scriptcat/pull/524

    // ==UserScript==
    // @name         Demo
    // @namespace    https://bbs.tampermonkey.net.cn/
    // @version      0.1.0
    // @description  try to take over the world!
    // @author       You
    // @match        *://*/*
    // @grant        unsafeWindow
    // ==/UserScript==
    
    console.log('---> demoooooooooooooooooooo start <---')
    console.log('变量', { a, b, c, d, e });
    console.log('dom', document.querySelector('#dom1'));
    document.querySelector('#closePage').addEventListener('click', () => window.close());
    console.log('---> demoooooooooooooooooooo end <---')
    
    a = 2;
    b = 3;
    c = 4;
    d = 5;
    // e是常量,不能修改
    // e = 6;
    
    console.log(window, this);
    
    window.b = 100;
    
    console.log('变量', { a, b, c, d, e });
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2025-7-22 00:22
  • 签到天数: 221 天

    [LV.7]常住居民III

    311

    主题

    4909

    回帖

    4576

    积分

    管理员

    积分
    4576

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2025-8-14 15:23:00 | 显示全部楼层

    我修改了一下教程内容,有什么疑问哥哥可以继续提出,我也好再次进行修改


    none和unsafeWindow

    简单来说:
    none就是直接运行在前端页面中,否则就是运行在一个沙盒环境,需要使用unsafeWindow去操作前端的元素。

    除了GM_* 函数外,还有两个特殊的权限,就是noneunsafeWindow

    默认情况下,你的脚本运行在油猴给你创建的一个半沙盒环境中,在这个沙盒环境中,你可以访问到页面上的元素,但是页面上的元素无法访问到脚本中的内容,用来隔离两个环境。

    b = 123;// 脚本中未定义b,会击穿沙盒到页面中去,此时:window.b=undefind,unsafeWindow=123;
    console.log(window.b, unsafeWindow.b);
    window.b = 234;// 在脚本的window中定义b,后续对b的操作都是在脚本的上下文中进行的,此时:window.b=234,unsafeWindow=123;
    console.log(window.b, unsafeWindow.b);
    b = 345; // 已经在脚本上下文中定义b了,效果同上,此时:window.b=345,unsafeWindow=123;
    console.log(window.b, unsafeWindow.b);
    unsafeWindow.b = 456; // 这里操作的是页面的对象,此时:window.b=345,unsafeWindow.b=456;
    console.log(window.b, unsafeWindow.b);
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    难过
    17 小时前
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    13

    主题

    71

    回帖

    100

    积分

    荣誉开发者

    积分
    100

    荣誉开发者油中2周年油中3周年新人报道挑战者 lv2喜迎中秋

    发表于 2025-8-14 15:43:44 | 显示全部楼层

    本帖最后由 wilsons 于 2025-8-15 11:34 编辑

    本帖最后由 wilsons 于 2025-8-15 11:32 编辑

    本帖最后由 wilsons 于 2025-8-15 11:17 编辑

    王一之 发表于 2025-8-14 15:02

    [md]教程有一些问题,你来听我狡辩一下:

    目前的沙盒是一个半沙盒的情况,教程中描述的是全沙盒的情况,教 ...

    感谢大佬!学习了!

    我测试了下,总结如下:

    1. 沙盒可以访问页面中的变量。
    2. 页面不能访问沙盒中的变量,但隐式全局变量(未声明变量的变量)除外,比如,m=1,这相当于unsafeWindow.m=1,但严格模式下会报错,闭包下也无效。
    3. 当油猴脚本grant none 时,window.xxx 可以修改页面中变量的值,此时油猴脚本中unsafeWindow是未定义。
    4. 当油猴脚本默认或grant unsafeWindow时,window.xxx 不能修改页面中变量的值,但unsafeWindow.xxx可以修改页面变量的值。

    测试代码如下:

    页面代码

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <title></title>
        </head>
    
        <body>
            <div id="dom1">dom 1</div>
            <button id="closePage">关闭页面</button>
            <script>
                var a=1;
                window.b=2;
                c=3;
                let d=4;
                const e = 5;
    
                setTimeout(()=>{
                    console.log('4秒后页面访问沙盒的变量', { a, b, c, d, e })
                    console.log('---> demoooooooooooooooooooo end2 <---')
                }, 4000)
            </script>
        </body>
    </html>

    油猴脚本代码

    // ==UserScript==
    // @name         Demo
    // @namespace    https://bbs.tampermonkey.net.cn/
    // @version      0.1.0
    // @description  try to take over the world!
    // @author       You
    // @match        *://*/*
    // ==/UserScript==
    
    console.log('---> demoooooooooooooooooooo start <---')
    console.log('变量', {a,b,c,d,e});
    console.log('dom', document.querySelector('#dom1'));
    document.querySelector('#closePage').addEventListener('click', ()=>window.close());
    console.log('---> demoooooooooooooooooooo end <---')
    
    a = 2;
    b = 3;
    c = 4;
    d = 5;
    // e是常量,不能修改
    // e = 6;
    
    window.b = 100; // @grant none 时生效
    unsafeWindow.b = 200; // 默认和@grant unsafeWindow时生效
    无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人。
    回复

    使用道具 举报

  • TA的每日心情
    难过
    17 小时前
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    13

    主题

    71

    回帖

    100

    积分

    荣誉开发者

    积分
    100

    荣誉开发者油中2周年油中3周年新人报道挑战者 lv2喜迎中秋

    发表于 2025-8-14 15:49:35 | 显示全部楼层
    王一之 发表于 2025-8-14 15:23
    [md]我修改了一下教程内容,有什么疑问哥哥可以继续提出,我也好再次进行修改

    ----

    感谢大佬!学习了!

    我刚才看了教程,感觉有些抽象,新手不容易理解。

    我觉得可以像我这个帖子中那样描述,页面中有什么变量,油猴脚本中如何访问,反过来,油猴有哪些变量,页面中如何访问等,这样去描述可能更清晰点。
    无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人。
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2025-7-22 00:22
  • 签到天数: 221 天

    [LV.7]常住居民III

    311

    主题

    4909

    回帖

    4576

    积分

    管理员

    积分
    4576

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2025-8-14 15:51:49 | 显示全部楼层
    wilsons 发表于 2025-8-14 15:49
    感谢大佬!学习了!

    我刚才看了教程,感觉有些抽象,新手不容易理解。

    已经更新过去了,有些地方哥哥也可以补充

    确实有实例的话,会更好理解一些,但是没那么多精力维护,而且出发角度不同也不会考虑到那么多
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    难过
    17 小时前
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    13

    主题

    71

    回帖

    100

    积分

    荣誉开发者

    积分
    100

    荣誉开发者油中2周年油中3周年新人报道挑战者 lv2喜迎中秋

    发表于 2025-8-14 15:55:22 | 显示全部楼层
    王一之 发表于 2025-8-14 15:51
    已经更新过去了,有些地方哥哥也可以补充

    确实有实例的话,会更好理解一些,但是没那么多精力维护,而且 ...

    ok!

    大佬辛苦了!
    无论从事什么行业,只要做好两件事就够了,一个是你的专业、一个是你的人。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表