前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >html5中如何解决canvas图片跨域问题-canvas无法导入远程图片

html5中如何解决canvas图片跨域问题-canvas无法导入远程图片

作者头像
超级小可爱
发布于 2023-11-08 02:39:39
发布于 2023-11-08 02:39:39
2.9K00
代码可运行
举报
文章被收录于专栏:小孟开发笔记小孟开发笔记
运行总次数:0
代码可运行

今天我们来说说在开发中比较常谈及的问题,那就是跨域问题,我们就来说说在:“html5中如何解决canvas图片getImageData,toDataURL跨域问题?”这个问题吧!

一、首先,图片服务器需要配置Access-Control-Allow-Origin

一般团队都会有一个专门域名放置静态资源,例如腾讯是 gtimg.com,百度是 bdimg.com;或者很多团队使用的是腾讯云或者阿里云的服务。

而主页面所在域名往往不一样,当需要需要对 canvas 图片进行​ getImageData() ​或​toDataURL()​操作的时候,跨域问题就出来了,而且跨域问题还不止一层。

首先,第一步,图片服务器需要配置​Access-Control-Allow-Origin​信息,例如:

如PHP添加响应头信息,*通配符表示允许任意域名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
header("Access-Control-Allow-Origin: *");

或者指定域名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
header("Access-Control-Allow-Origin: www.zhangxinxu.com");

此时,Chrome 浏览器就不会有 ​Access-Control-Allow-Origin ​相关的错误信息了,但是,还会有其他的跨域错误信息。

二、canvas图片getImageData cross-origin跨域问题

对于跨域的图片,只要能够在网页中正常显示出来,就可以使用 canvas 的​drawImage() ​​API​绘制出来。但是如果你想更进一步,通过​getImageData()​方法获取图片的完整的像素信息,则多半会出错。

举例来说,使用下面代码获取 github 上的自己头像图片信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

结果在Chrome浏览器下显示如下错误:

Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.

Firefox浏览器错误为:

SecurityError: The operation is insecure.

如果使用的是canvas.toDataURL()方法,则会报:

Failed to execute ‘toDataURL’ on ’HTMLCanvasElement’: Tainted canvased may not be exported

原因其实都是一样的,跨域导致。

那有没有什么办法可以解决这个问题呢?

可以试试 crossOrigin 属性。

三、HTML crossOrigin属性解决资源跨域问题

在HTML5中,有些元素提供了支持​CORS(Cross-Origin Resource Sharing)​(跨域资源共享)的属性,这些元素包括<img>,​<video>​,​<script>​等,而提供的属性名就是​crossOrigin​属性。

因此,上面的跨域问题可以这么处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = '';
img.onload = function () {
    context.drawImage(this, 0, 0);
    context.getImageData(0, 0, this.width, this.height);
};
img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';

增加一个img.crossOrigin = ”即可,虽然JS代码这里设置的是空字符串,实际上起作用的属性值是 anonymous。

crossOrigin​可以有下面两个值:

关键字

释义

anonymous

元素的跨域资源请求不需要凭证标志设置。

use-credentials

元素的跨域资源请求需要凭证标志设置,意味着该请求需要提供凭证。

其中,只要 crossOrigin 的属性值不是 use-credentials,全部都会解析为 anonymous,包括空字符串,包括类似’abc’这样的字符。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
img.crossOrigin = 'abc';
console.log(img.crossOrigin);    // 结果是'anonymous'

另外还有一点需要注意,那就是虽然没有 crossOrigin 属性,和设置 crossOrigin=”use-credentials” 在默认情况下都会报跨域出错,但是性质上却不一样,两者有较大区别。

crossOrigin兼容性

IE11+(IE Edge),Safari,Chrome,Firefox浏览器均支持,IE9和IE10会报SecurityError安全错误,如下截图:

四、crossOrigin属性为什么可以解决资源跨域问题?

crossOrigin=anonymous相对于告诉对方服务器,你不需要带任何非匿名信息过来。例如cookie,因此,当前浏览器肯定是安全的。

就好比你要去别人家里拿一件衣服,crossOrigin=anonymous相对于告诉对方,我只要衣服,其他都不要。如果不说,可能对方在衣服里放个窃听器什么的,就不安全了,浏览器就会阻止。

五、IE10浏览器不支持crossOrigin怎么办?

我们请求图片的时候,不是直接通过new Image(),而是借助ajax和URL.createObjectURL()方法曲线救国。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    var img = new Image();
    img.onload = function () {
        // 此时你就可以使用canvas对img为所欲为了
        // ... code ...
        // 图片用完后记得释放内存
        URL.revokeObjectURL(url);
    };
    img.src = url;
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();

此方法不仅IE10浏览器OK,原本支持crossOrigin的诸位浏览器也是支持的。

也就多走一个ajax请求,还可以!

根据,根据实践发现,在IE浏览器下,如果请求的图片过大,几千像素那种,图片会加载失败,我猜是超过了blob尺寸限制。

六、结束语

那么这就是有关于:“html5中如何解决canvas图片getImageData,toDataURL跨域问题?”这个问的相关内容,当然更多的相关内容我们都可以在W3Cschool中进行学习和了解。

未经允许不得转载:肥猫博客 » html5中如何解决canvas图片跨域问题-canvas无法导入远程图片

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Kali Linux没有IPv4地址解决方法
我的kali是烧录在U盘的 运行环境为U盘 kali能够检测到网卡 但是没有ipv4地址解决方法
菜菜有点菜
2022/03/16
5.3K2
Kali Linux没有IPv4地址解决方法
如何在 Linux 中配置 IPv4 和 IPv6 地址?
IPv4和IPv6是Internet上常用的两种IP地址协议。在Linux系统中,您可以通过配置网络接口来设置IPv4和IPv6地址。本文将详细介绍如何在Linux中配置IPv4和IPv6地址。
网络技术联盟站
2023/06/20
3.3K0
如何在 Linux 中配置 IPv4 和 IPv6 地址?
Kali-Security渗透系统配置记录
描述:Kail 是基于Debian的Linux发行版它的前身是BackTrack并且由Offensive Security Ltd维护和资助,设计用于渗透测试与取证的系统,系统里面集成了超过300个渗透测试工具复,受到广大的网络安全从业者与爱好者的追捧;
全栈工程师修炼指南
2020/10/26
1.1K0
linux中10个有用的IP命令配置静态IP路由
ip 命令是一个新的网络命令行实用程序,用于在 Linux 系统上为网络接口分配 IP 地址或配置/更新网络配置。 它是 iproute2 软件包的一部分,并提供多项网络管理任务,例如打开或关闭网络接口、分配和删除 IP 地址和路由、管理 ARP 缓存等等。 ip命令与旧的ifconfig 命令非常相似,但它的功能要强大得多,添加了更多的功能和能力。 如何配置静态 IP 地址 Internet 协议 (IPv4) 要在 Linux 中配置静态 IP 地址, 你需要更新或编辑网络配置文件以将静态 IP 地址分
入门笔记
2022/06/02
3.9K0
kali2020 永久性网络配置
查看ip:ip address(ip a) (kali2020 不支持ifconfig查看ip)
宸寰客
2020/07/13
2.7K0
kali2020 永久性网络配置
ubuntu 常用问题解决方法ubuntu11.04升级到11.10 启动不起来(booting system without full network configuration)
sudo vim /etc/NetworkManager/NetworkManager.conf 将 managed=false
sinnoo
2021/07/27
1.9K0
检查 centos 系统上的网络连接
Linux 上有许多可用于查看网络设置和连接的命令。在今天的文章中,我们将会通过一些非常方便的命令来看看它们是如何工作的。
用户1685462
2021/09/13
2.2K0
ubuntu网络的设置方式
ubuntu系统进行网络配置有的时候用图形界面不起作用,这种情况下可以直接修改某些启动脚本或配置文件 Ubuntu系统进行网络配置涉及到几个配置文件1./etc/network/interfaces 2./etc/resolv.conf 操纵步骤: 1.打开ubuntu的/etc/network/interfaces文件默认的内容如下: auto lo iface lo inet loopback 动态获取的配置方法: auto eth0 iface eth0 inet dhcp 静态分配的配置方法: auto eth0 iface eth0 inet static address 192.168.0.1 netmask 255.255.255.0 gateway 192.168.0.1 根据配置要求(是动态分配还是自动获取)修改该配置文件保存。
零式的天空
2022/03/02
2.6K0
ubuntu网络的设置方式
kali基础教程第二篇(kali下的相关配置)
1.修改用户配置文件/etc/shadow 将第二栏设置为*,如下。那么该用户就无法登录。但是使用这种方式会导致该用户的密码丢失,也就是当你再次允许他登录的时候,你还得让他重新设置密码。[再次启用这个帐号的方法是把*去掉就可以了
逍遥子大表哥
2021/12/19
1.1K0
kali基础教程第二篇(kali下的相关配置)
Linux实践|设置静态 IP 地址
如果您是 Linux 系统管理员,那么您将需要在系统上配置网络。与可以使用动态 IP 地址的台式机不同,在服务器基础设施上,您需要设置静态 IP 地址(至少在大多数情况下)。
数据科学工厂
2024/12/30
5150
Linux实践|设置静态 IP 地址
虚拟机中的kali linux没有了eth0,只有lo接口了怎么办
用户1423082
2024/12/31
1380
Linux配置IP地址的方法
注:虚拟机系统通过克隆方式得到其他系统后,在同一网络中无法上网,很可能由于其网卡的UUID相同造成冲突引起的。 解决方案:
全栈程序员站长
2022/06/26
8.8K0
《21天精通IPv4 to IPv6》第3天:IPv6地址配置——如何为不同的系统配置IPv6?
今天,作为猫头虎博主,我将指导大家在不同操作系统中配置IPv6地址。我们将覆盖从静态到动态的地址配置,以及在Windows、Linux、macOS、Android以及国产操作系统中的具体配置步骤。本文包含丰富的技术词条,如IPv6配置、操作系统IPv6设置、网络配置技巧,确保每位读者都能轻松理解并应用这些知识。
猫头虎
2024/04/09
2.3K0
《21天精通IPv4 to IPv6》第3天:IPv6地址配置——如何为不同的系统配置IPv6?
ubuntu虚拟机ip地址设置_网络虚拟ip地址怎么弄
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
全栈程序员站长
2022/11/01
1.7K0
ubuntu虚拟机ip地址设置_网络虚拟ip地址怎么弄
Debian中如何设置静态IP地址 网关 DNS
新安装的Debian系统,默认一般使用DHCP获取IP地址,除非在安装过程中,使用了指定的IP地址。本文将介绍如何在Debian系统中,配置使用静态IP地址,配置网关,以及设置DNS服务器。
Debian中国
2018/12/20
9.8K0
ubuntu14.04如何设置静态IP的方法
注意:重启Ubuntu后发现不能上网,问题出现在/etc/resolv.conf。重启后,此文件配置的dns又被自动修改为默认值。所以需要永久性修改DNS。方法为
yaohong
2019/09/11
1.1K0
网络空间安全之一个WH的超前沿全栈技术深入学习之路(六:保姆级教会你如何对Kali本地网络配置、 sshd 服务并使用 xshell 连接:就怕你学成黑客啦!)作者——LJS
盛透侧视攻城狮
2024/10/24
1030
网络空间安全之一个WH的超前沿全栈技术深入学习之路(六:保姆级教会你如何对Kali本地网络配置、 sshd 服务并使用 xshell 连接:就怕你学成黑客啦!)作者——LJS
Linux环境下查看IP不显示IPv4地址
这篇文章记录一下,当我在虚拟机下运行Ubuntu时,想在我的windows下通过putty连接到Linux系统,但发现连接不上,之后在Ubuntu下查看ip,发现显示的内容里没有我想要的IP地址。 现在来记录一下解决办法。
跋扈洋
2022/03/29
5.2K0
Linux环境下查看IP不显示IPv4地址
超详细kali linux 设置固定IP地址步骤
打开VMware Workstation,在已经创建好的虚拟机“TEST 虚拟机创建”上面编辑虚拟机设置,点击“网络适配器”,弹出窗口在网络连接中选择“桥接模式(B)直接连接物理网络”。(不要选择:“复制物理网络连接状态”!)
全栈程序员站长
2022/08/25
10.7K0
超详细kali linux 设置固定IP地址步骤
玩玩树莓派之自动连接无线路由器
前言:啥都没有,还是说说自己的心声,还是啥都没有,嘿嘿,又一段时间没有玩过树莓派了,连连接无线路由器都忘记啦,所以我是来记录记录此过程的。 ---- Step-One:手机安装Fing软件 安装此软件的目的是扫描局同一段域网的IP,想要ssh到树莓派必须知道IP的啦 ---- Step-Two:ssh到树莓派主机,既然都知道了树莓派IP那就ssh上去 ssh pi@172.16.168.125 #默认用户名为pi 密码为raspberry ---- Step-Three:修改网络配置文件/etc
AlicFeng
2018/06/08
6950
推荐阅读
相关推荐
Kali Linux没有IPv4地址解决方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档