【发布时间】:2016-06-28 01:04:51
【问题描述】:
这个想法在概念上非常简单: 我想创建一个用户脚本,让我按下一个按钮并在页面上保存一些东西(最常见和有问题的图像)。 注意:用户脚本是客户端注入的脚本(通过 Tampermonkey 和 Greasemonkey 等浏览器扩展),用于向网站添加功能。
为此,我只需要调用saveAs() 函数并将数据传递给它。
然后问题就变成了我如何获取数据。
我见过的大多数方法都可能遇到资源与脚本不在同一个域的情况?(不确定这是如何工作的)。
现在,Tampermonkey(和 Greasemonkey)创建了一个专门处理这个问题的函数 - GM_XMLHTTPRequest,它可以规避对适当 CORS 标头的需求。
然而,这会为已下载的文件创建另一个对服务器的请求。
我的问题是:有没有办法不必向服务器发送辅助请求?
这是我努力的编年史:
根据我所做的研究,您可以创建一个canvas 并在其中绘制图像。但是,这会“污染”画布,使其无法运行提取该数据的函数(例如 .toBlob() 或 .toDataURL())。
据我了解,CORS 提供了 2 种机制:设置正确的 HTTP 标头,这需要控制服务器,以及可以放在 HTML 元素上的特殊属性:crossorigin
我尝试在加载后添加此属性,但它不起作用,您仍然会得到一个受污染的画布。
Tampermonkey 提供了几个关于何时运行脚本的不同选项。所以下一个想法是在 DOM 加载但尚未获取资源时运行。似乎最早可能是文档结束(之前getElementById 调用返回null)。但是,当前在页面上加载图像时会返回错误(在运行任何其他附加代码之前):
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 标志,但我宁愿不去那里。
【问题讨论】:
-
所以你的图片数据和你的网页数据不在同一个域上?与您的网络域相关的图像来源在哪里?
-
如果您只是想在浏览器中将特定图像另存为 jpg 或 png 之类的下载文件,我已经做到了。无需再次调用服务器,也不知道为什么 CORS 会成为问题。如果是这样,我可以提供一些提示。
-
@Binvention 我不知道它如何与用户脚本一起使用,但所有错误都与违反同源策略有关。网页在
page.com,图片在images.page.com@Will 是的,请。如果他们适用于这种情况,欢迎提供任何提示。 -
是的,这会干扰跨域,因为子域不被视为相同。例如 example.com 与 image.example.com 不是同一个域但是 example.com 与 example.com/images 就跨域安全性而言相同,解决方案是添加您的错误所指的标题离开服务器之前的图像标题
-
因此,您可以将标题 'Access-Control-Allow-Origin'='yourpagedomainhere' 添加到图像标题中
标签: javascript canvas cors cross-domain tampermonkey