crossorigin属性决定浏览器是否允许JavaScript读取跨域图片像素数据,而非控制图片能否显示;它必须与服务端Access-Control-Allow-Origin响应头配合生效,否则canvas会被污染导致toDataURL()或getImageData()抛SecurityError。
它不解决跨域图片“能不能显示”的问题,只决定浏览器是否允许 JavaScript 读取该图片的像素数据(比如用 canvas.getContext('2d').getImageData())。如果没设或设错,toDataURL() 或 getImageData() 会直接抛 SecurityError: The canvas has been tainted by cross-origin data.
单独在 <img> 上加 crossorigin 没用——服务端得返回 Access-Control-Allow-Origin 响应头,否则浏览器连图片都拒绝加载(尤其当 crossorigin="use-credentials" 时)。
crossorigin="anonymous":发请求时不带 cookie / auth header;服务端只需返回 Access-Control-Allow-Origin: * 或具体域名crossorigin="use-credentials":带 cookie 和认证信息;服务端必须返回 Access-Control-Allow-Origin: https://your-site.com(不能是 *),且通常还需 Access-Control-Allow-Credentials: true
这些写法看似合理,实际都会导致 canvas 被污染或请求失败:
crossorigin 但没写值 → 浏览器按空字符串处理,等价于 crossorigin="anonymous",但部分 CDN 会忽略空值,结果仍是污染crossorigin="anonymous",但服务端返回的是 Access-Control-Allow-Origin: https://example.com(不匹配当前域名)→ 图片加载失败,控制台报 Blocked loading resource from url ... because it violates the following Content Security Policy directive 类似错误new Image() 动态创建图片但忘了设置 crossOrigin 属性 → 即使 HTML 里 img 标签写了,JS 创建的实例也默认不跨域,必须显式赋值:img.crossOrigin = 'anonymous'
遇到 canvas 被污染,按顺序确认这几项:
立即学习“前端免费学习笔记(深入)”;
crossorigin="anonymous"(注意拼写,不是 crossorigin 或 crossOrigin)Access-Control-Allow-Origin
onload,否则可能因异步时机问题误判为污染跨域图片能显示 ≠ 能读像素,这个边界最容易被忽略。服务端没配好,前端加再多 crossorigin 都只是摆设。