创建一个 "Save As" 用户脚本

Create a "Save As" userscript

这个想法在概念上很简单: 我想创建一个用户脚本,让我按下一个按钮并在页面上保存一些东西(最常见和有问题的图像)。 注意:用户脚本是 client-side(通过 Tampermonkey 和 Greasemonkey 等浏览器扩展)注入的脚本,用于向站点添加功能。

为此,我只需要调用 saveAs() 函数并将数据传递给它。

那么问题就变成了我如何获取数据。

我见过的大多数方法 运行 可能会遇到资源与脚本不在同一个域的情况?(不确定这是如何工作的)。

现在,Tampermonkey(和 Greasemonkey)已经创建了一个函数来专门处理这个问题 - GM_XMLHTTPRequest,它可以避免对适当 CORS 的需求 headers。

然而,这会为已下载的文件创建另一个对服务器的请求。

我的问题是:有没有办法不必向服务器发送二次请求?


这是我努力的记录:

根据我所做的研究,您可以创建一个 canvas 并在其中绘制图像。但是,"taints" canvas 阻止了它 运行 提取该数据的函数(例如 .toBlob().toDataURL())。
据我所知,CORS 提供了 2 种机制:设置正确的 HTTP headers,这需要控制服务器,以及可以放在 HTML 元素上的特殊属性:crossorigin
我尝试添加这个 属性 post-load 但它不起作用,你仍然得到一个受污染的 canvas.
Tampermonkey 提供了几种不同的选项来决定何时 运行 脚本。所以下一个想法是在加载 DOM 时 运行 ,但尚未获取资源。似乎最早可能是 document-end(更早的 getElementById 调用 returns null)。然而,目前 returns 在页面上加载图像时出现错误(在任何其他附加代码之前 运行): Image from origin '...' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access.
Chrome 中也有 --disable-web-security 标志,但我不想去那里。

不,如果不向服务器发出新请求,则无法执行此操作。

当发出第一个请求时,图像被浏览器标记为不安全,然后将阻止一些功能,例如 canvas' toDataURLgetImageDatatoBlob,或者在音频文件的情况下,AudioContext 的 createMediaElementSourceAnalyserNode 的方法以及可能的其他一些方法。

您无法规避此安全措施,一旦它被标记为不安全,它就是不安全的。 这次您必须向服务器发出新请求,以安全的方式从服务器获取新文件。

通常,您只需在发出请求之前设置媒体元素的 crossOrigin 属性,并在正确配置服务器以响应此类请求之后。

现在在你的情况下,很明显你不能配置任何将使用你的脚本的服务器。

但是正如您所注意到的,GreaseMonkey 或 TamperMonkey 等扩展程序可以从网页访问比基本 javascript 运行 更多的功能。在这些特性中,有一个允许你的浏览器对这种跨源请求不那么小心,这就是 GM_xmlhttpRequest 方法所做的。

但再一次,即使是扩展程序也没有足够的能力取消标记非安全媒体。

您必须使用安全性较低的方式执行新请求。