启用了 CORS 的图片 - HTML(超文本标记语言) 编辑
HTML 规范中图片有一个
属性,结合合适的 crossorigin
CORS
响应头,就可以实现在画布中使用跨域
元素的图像,就像在原生 <img>
中使用一样。<canvas>
查看 CORS settings attributes 来了解更多 crossorigin
属性的用法。
安全性和“被污染”的 canvas
由于在
位图中的像素可能来自多种来源,包括从其他主机检索的图像或视频,因此不可避免的会出现安全问题。<canvas>
尽管不通过 CORS 就可以在
中使用其他来源的图片,但是这会污染画布,并且不再认为是安全的画布,这将可能在 <canvas>
检索数据过程中引发异常。<canvas>
如果从外部引入的 HTML
或 SVG <img>
,并且图像源不符合规则,将会被阻止从 <svg>
中读取数据。<canvas>
在"被污染"的画布中调用以下方法将会抛出安全错误:
- 在
的上下文上调用<canvas>
getImageData()
- 在
上调用<canvas>
toBlob()
- 在
上调用<canvas>
toDataURL()
这种机制可以避免未经许可拉取远程网站信息而导致的用户隐私泄露。
示例: 存储一张外部域中的图片
在以下例子中,将实现允许检索来自外部的图像,并将其保存在本地存储。要实现这一点,我们需要配置服务器以及网站本身的编码。
网站服务器配置
首先,你必须有一个可以对图片响应正确 Access-Control-Allow-Origin
响应头的服务器。你可以使用以下片段 (来自 HTML5 Boilerplate Apache server configs) 实现正确响应头,该配置为允许跨域访问图片。
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
现在已经将服务器配置为允许跨源检索这些不同格式的图像。
实现保存功能
配置完毕后,你就可以将这些格式的图片保存到本地 DOM 存储 中了,就像这些图片在你自己域名之下一样。
在
上设置 HTMLImageElement
的 crossOrigin
属性,这将允许浏览器在下载图像数据时允许跨域访问请求。crossorigin
开始下载图片
以下代码将在用户点击 "Download
" 按钮时开始下载:
function startDownload() {
let imageURL = "https://cdn.glitch.com/4c9ebeb9-8b9a-4adc-ad0a-238d9ae00bb5%2Fmdn_logo-only_color.svg?1535749917189";
downloadedImg = new Image;
downloadedImg.crossOrigin = "Anonymous";
downloadedImg.addEventListener("load", imageReceived, false);
downloadedImg.src = imageURL;
}
使用 "硬编码" 图片网址可以很方便的允许图片来自任何地址。当开始下载图片时,我们使用
构造器创建新的 Image()
对象,将图片的 HTMLImageElement
crossOrigin
属性设置为"匿名
"(即,允许对未经过验证的图像进行跨域下载)。添加图片的
事件的监听来判断图片数据是否已接收。load
最后,将图片的
属性设置为图片的URL以触发图片下载。src
接收和保存图片
在 imageReceived()
方法中来处理新下载的图片:
function imageReceived() {
let canvas = document.createElement("canvas");
let context = canvas.getContext("2d");
canvas.width = downloadedImg.width;
canvas.height = downloadedImg.height;
context.drawImage(downloadedImg, 0, 0);
imageBox.appendChild(canvas);
try {
localStorage.setItem("saved-image-example", canvas.toDataURL("image/png"));
}
catch(err) {
console.log("Error: " + err);
}
}
在 HTMLImageElement
调用 imageReceived()
来处理"load
" 事件以接收下载图片。一旦下载完成全部有效的数据即可触发该事件。从创建新
元素将图像转换为数据URL,到访问画布的变量 <canvas>
context
中的2D绘图上下文 (
.CanvasRenderingContext2D
)
调整画布大小以匹配接收到的图像,然后使用
将图像绘制到画布中。画布之后被插入到文档中显示。drawImage()
我们使用 Web Storage API 的本地存储机制来将图片实际存储到本地,该机制可通过全局
进行访问。localStorage
canvas
的
方法用于将图像转换为 data:// URL 形式的 PNG 格式图片,之后使用 toDataURL()
存储到本地。setItem()
浏览器兼容性
We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基础支持 | 13 | 8 | 未实现 | 未实现 | ? |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
基础支持 | ? | ? | ? | ? | ? |
另请参阅
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论