javascript - 创建 "Save As"用户脚本

标签 javascript canvas cors cross-domain tampermonkey

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

为此,我只需要调用 saveAs() 函数并向其传递数据。

接下来的问题就变成了如何获取数据。

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

现在,Tampermonkey(和 Greasemonkey)创建了一个函数来专门处理这个问题 - GM_XMLHTTPRequest,它可以避免对正确的 CORS header 的需要。

但是,这会向服务器创建另一个请求,以获取已下载的文件。

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

<小时/>

这是我的努力记录:

根据我所做的研究,您可以创建一个 Canvas 并在其中绘制图像。然而,这会“污染” Canvas ,阻止其运行提取该数据的函数(例如 .toBlob().toDataURL())。
据我了解,CORS 提供了 2 种机制:设置正确的 HTTP header ,这需要对服务器进行控制,以及可以放在 HTML 元素上的特殊属性:crossorigin
我尝试在加载后添加此属性,但它不起作用,您仍然会得到一个受污染的 Canvas 。
Tampermonkey 提供了几个关于何时运行脚本的不同选项。因此,下一个想法是在 DOM 加载但尚未获取资源时运行。看来最早可能是文档结束(之前 getElementById 调用返回 null)。但是,当前在页面上加载图像时(在运行任何其他附加代码之前)会返回错误: 来自来源“...”的图像已被跨源资源共享策略阻止加载:请求的资源上不存在“Access-Control-Allow-Origin” header 。因此,不允许访问源“...”。
Chrome 中还有 --disable-web-security 标志,但我不想去那里。

最佳答案

不,如果没有向服务器发出新请求,就无法做到这一点。

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

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

通常,您只需在执行请求之前以及在服务器正确配置为响应此类请求之后在媒体元素上设置 crossOrigin 属性即可。

现在,就您的情况而言,很明显您无法配置将使用脚本的任何服务器。

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

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

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

关于javascript - 创建 "Save As"用户脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35963036/

相关文章:

javascript - chop 前 120 个字符后的所有内容并刷新

javascript - ECMAScript 6 类中静态方法的用途

html - 使用不同屏幕尺寸的 Canvas

javascript - 我将 X Y Z 坐标转换为屏幕 X Y 坐标有什么问题?

javascript - 使用 Fabric.js 创建空心圆

javascript - 在 onpaste 事件中发出 ajax 请求时访问被拒绝

javascript文本匹配计数和正则表达式空格不起作用

javascript - 显示特定的键值对

web - 为什么同源策略会阻止读取 GET 响应?

docker - CORS 在带有 NGINX 的 Docker-Compose 堆栈中的某处失败 - 找不到它