bilibili merged flv+mp4+ass+enhance

bilibili/哔哩哔哩:超清FLV下载,FLV合并,原生MP4下载,弹幕ASS下载,MKV打包,播放体验增强,原生appsecret,不借助其他网站

< Feedback on bilibili merged flv+mp4+ass+enhance

Question/comment

§
Posted: 2017-08-01
Edited: 2017-08-01

关于greasemonkey无法运行原因和解决的思路

我粗略的调试了你的脚本,发现主要是hook了jquery的ajax函数这一阶段发生了问题。

Firefox提供了一个叫SandBox 和 Xray vision(https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision)的机制 ,greasemonkey也同样使用了这两个东西。
前者SB,主要是限制gm脚本调用有特权的api,后者则是防止网页调用gm脚本不小心暴露出来的api。

1. jquery的ajax运行的上下文环境是页面的window
2. gm脚本的运行上下文环境是gm自己构造的window,这里可以使用gm的特殊函数如GM_setValue
(可以添加//@grant unsafeWindow 后可以在gm脚本中用unsafeWindow这个变量来指代页面的window)
我想使用书签方式可以正常运行的原因主要是 运行环境一致。

我的认为可行解决方法是:
既然脚本只使用到了 setValue 和 getValue这两个普通的api,那么完全可以放弃它们,把数据存放在localStorage或indexedDB中。
然后把整个脚本转换成字符串插入到document中执行。

如果确实需要使用 setValue 和 getValue,我有一个还没有验证的想法:创建元素(其实什么类型都可以),隐藏起来,在gm脚本中监听点击事件。此时这个元素就充当了一个数据传输的中介。
通过使用 a.click() 或 a.textContent 就可以得到想要的数据

这一切都是我的假设,仅供参考。

qli5Author
§
Posted: 2017-08-01
我粗略的调试了你的脚本,发现主要是hook了jquery的ajax函数这一阶段发生了问题。

Firefox提供了一个叫SandBox 和 Xray vision(https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Xray_vision)的机制 ,greasemonkey也同样使用了这两个东西。
前者SB,主要是限制gm脚本调用有特权的api,后者则是防止网页调用gm脚本不小心暴露出来的api。

1. jquery的ajax运行的上下文环境是页面的window
2. gm脚本的运行上下文环境是gm自己构造的window,这里可以使用gm的特殊函数如GM_setValue
(可以添加//@grant unsafeWindow 后可以在gm脚本中用unsafeWindow这个变量来指代页面的window)
我想使用书签方式可以正常运行的原因主要是 运行环境一致。

我的认为可行解决方法是:
既然脚本只使用到了 setValue 和 getValue这两个普通的api,那么完全可以放弃它们,把数据存放在localStorage或indexedDB中。
然后把整个脚本转换成字符串插入到document中执行。

如果确实需要使用 setValue 和 getValue,我有一个还没有验证的想法:创建元素(其实什么类型都可以),隐藏起来,在gm脚本中监听点击事件。此时这个元素就充当了一个数据传输的中介。
通过使用 a.click() 或 a.textContent 就可以得到想要的数据

这一切都是我的假设,仅供参考。




多谢阁下参加讨论。

TL; DR: 现有脚本直接改成grant none即可运行,但是本脚本在火狐会严重内存泄露,所以还是不推荐使用。
点我到开发分支去吃螃蟹

我之前用greasemonkey做了以下实验:
window.foo1 = 123; // ReferenceError: foo1 is not defined
unsafeWindow.foo2 = 123; // OK
unsafeWindow.foo3 = () => {}; // Error: Permission denied to access object
unsafeWindow.eval('window.foo4 = () => {}'); // OK, but ugly
window.eval('window.foo5 = () => {}'); // OK, but ugly and confusing
unsafeWindow.foo6 = window.eval('() => {}'); // OK, but still ugly
可以看出,这不仅仅是简单的作用域隔离,可能检测了callee。grant unsafeWindow无变化。这个grant貌似已经废弃。

关于unsafeWindow的问题,我这两天也看了一些文档。根据GreaseSpot,无权限要求的脚本可以直接插入页面作用域。因为一开始就有localStorage作为后备方案,所以简单地grant none可以直接让脚本跑起来。

我有些困惑……这到底是greasemonkey太过严苛还是tampermonkey安全堪忧。可能hook jQuery太常见了,tampermonkey的$甚至直接是暴露过来的,我在hook fetch的时候才发现了wrapper。定义setter和getter之后,fetch也直接暴露过来了,写的很顺手。

其实我觉得有意地把接口暴露出去也是正常需求,像“解除B站区域限制”,CORS自然最好,但要是控制不了服务器,用GM跨域也无可厚非。写的时候既然打了unsafe,就意味着已经做过取舍了。

不过火狐还是有些问题……我用Chrome优化到现在,内存占用只会出现短暂的1.2倍文件大小的峰值,之后会快速稳定到0.3倍;火狐会爆炸 :) 所以还是不推荐使用了。

Deleted user 108456
§
Posted: 2017-08-02

localStorage 最讨厌的是脚本移除了数据还保留着

Post reply

Sign in to post a reply.