Javascript 创建一个";另存为;用户脚本

Javascript 创建一个";另存为;用户脚本,javascript,canvas,cors,cross-domain,tampermonkey,Javascript,Canvas,Cors,Cross Domain,Tampermonkey,这个想法在概念上非常简单: 我想创建一个用户脚本,让我按下一个按钮,并在页面上保存一些东西(最常见和有问题的图像)。 注意:userscript是一种注入客户端的脚本(通过浏览器扩展,如Tampermonkey和Greasemonkey),用于向站点添加功能。 为此,我只需要调用saveAs()函数并将数据传递给它 接下来的问题是如何获取数据 我见过的大多数方法都会遇到这样的情况,即资源可能与脚本不在同一个域中(不确定这是如何工作的) 现在,Tampermonkey(和Greasemonkey)

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

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

接下来的问题是如何获取数据

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

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

但是,这会为服务器创建另一个已下载文件的请求

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


以下是我的工作记录:

根据我所做的研究,您可以创建一个
画布
,并在其中绘制图像。但是,这会“污染”画布,使其无法运行提取该数据的函数(例如
.toBlob()
.toDataURL()
)。
据我所知,CORS提供了两种机制:设置正确的HTTP头,这需要控制服务器,以及一个可以放在HTML元素上的特殊属性:
crossorigin

我尝试在加载后添加此属性,但它不起作用,您仍然会得到一个受污染的画布。
Tampermonkey提供了几个关于何时运行脚本的不同选项。因此,下一个想法是在加载DOM时运行,但尚未获取资源。似乎最早的可能是文档结束(更早的
getElementById
调用返回
null
)。但是,当前在页面上加载图像时(在运行任何其他代码之前)返回错误: 跨源资源共享策略已阻止加载来自源“…”的图像:请求的资源上不存在“访问控制允许源”标头。因此,不允许访问源“…”。

Chrome中还有禁用web安全的标志,但我不想去那里。

不,如果没有对服务器的新请求,就无法做到这一点

当发出第一个请求时,浏览器会将图像标记为不安全,然后会阻止一些功能,如canvas’
toDataURL
getImageData
toBlob
,或者如果是音频文件,AudioContext的
createMediaElementSource
AnalyzerNode
的方法,可能还有其他一些方法

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

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

现在,在您的情况下,很明显您无法配置任何将在其中使用脚本的服务器

但正如您所注意到的,像GreaseMonkey或TamperMonkey这样的扩展可以访问比网页上运行的基本javascript更多的功能。在这些特性中,有一个特性允许浏览器对此类跨源请求不那么小心,这就是该方法的作用

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


您必须使用不太安全的方式执行新请求。

不,如果没有对服务器的新请求,就无法执行新请求

当发出第一个请求时,浏览器会将图像标记为不安全,然后会阻止一些功能,如canvas’
toDataURL
getImageData
toBlob
,或者如果是音频文件,AudioContext的
createMediaElementSource
AnalyzerNode
的方法,可能还有其他一些方法

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

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

现在,在您的情况下,很明显您无法配置任何将在其中使用脚本的服务器

但正如您所注意到的,像GreaseMonkey或TamperMonkey这样的扩展可以访问比网页上运行的基本javascript更多的功能。在这些特性中,有一个特性允许浏览器对此类跨源请求不那么小心,这就是该方法的作用

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


您必须使用不太安全的方式执行新请求。

所以您的图像数据与您的网页数据不在同一域中?相对于您的web域,您的图像来源在哪里?如果您只想将特定图像保存为在浏览器中下载到jpg或png之类的内容,我已经这样做了。不需要再次调用服务器,也不确定为什么CORS会成为一个问题。如果是这样的话,我可以提供一些提示。@b我不知道如何使用userscripts,但所有错误都与违反同源策略有关。网页位于
page.com
,图像位于
images.page.com
@是的。如果他们在这种情况下适用,任何提示都是受欢迎的。是的,这会干扰跨源,因为子域不一致