网站最近访问有点慢,主要是首页全屏 Banner 图片有点大,加载有点慢。于是决定启用 CDN 缓存静态文件来提升下网站加载速度。启用后发现网站海报生成图片报错(Uncaught DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Taninted canvases may not be exported. ),具体报错信息如下:

错误原因好像是出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求,即同源安全策略。可以通过配置跨域资源共享( CORS )机制以允许 Web 应用服务器进行跨域访问控制,进而使跨域数据传输得以安全进行。CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。针对这里的报错信息,我们可以通过 setAttribute 方法来设置 crossOrigin 属性以允许相应资源的跨域请求。

由于目前我生成的海报中仅有特色图像与 Logo (图中红框区域)内容是跨域图片,日期是自动生成的,二维码是通过 jquery.cookie.min.js 插件生成的,所以这里仅设置这两个图片允许跨域请求即可,代码如下:

// Logo 图标
var logo = new Image();
logo.setAttribute("crossOrigin",'Anonymous');
logo.src = config.logo;
// 特色图像
var banner = new Image();
banner.setAttribute("crossOrigin",'Anonymous');
banner.src = config.banner;

注意:需要在获取图片前设置 crossOrigin 属性。

最后,crossOrigin 的取值及其解释如下:
anonymous:执行跨域请求(即带有HTTP标头),但不发送凭据(即不发送cookie,X.509证书或HTTP Basic身份验证)。如果服务器未将凭据提供给原始站点(未设置HTTP标头),则该图像将被污染并且其使用受到限制。

use-credentialsOrigin与发送的凭据(即cookie,证书或HTTP Basic身份验证)一起执行跨域请求(即带有HTTP标头)。如果服务器未(通过Access-Control-Allow-CredentialsHTTP标头)将凭据提供给原始站点,则该图像将被污染并且其使用受到限制。

“”:如果属性不存在,则在没有CORS请求的情况下(即,不发送OriginHTTP头)获取资源,从而防止其在<canvas>元素中的无污染使用。如果值无效,则将其视为anonymous已使用该值。

参考文档: