预加载图片跨域问题本质是后续JS操作被拦截,需同时设置img.crossOrigin='anonymous'(必须在src前)和服务端返回Access-Control-Allow-Origin响应头,否则canvas会报tainted错误。

预加载图片时遇到跨域,本质不是“加载失败”,而是后续 JS 操作(比如 canvas 像素读取、html2canvas 截图)被浏览器拦截——因为图片没走 CORS 流程,canvas 一碰就报 tainted canvas 错误。
img.crossOrigin = 'anonymous' 必须在设置 src 前赋值
这是最常踩的坑:顺序错了,CORS 请求根本不会发出去。
-
img.src设在img.crossOrigin之前 → 浏览器按普通非 CORS 方式加载,缓存里存的是“无跨域许可”的版本 - 后续哪怕再设
crossOrigin,也无法复用缓存,canvas 绘制时直接拒绝 - 正确写法必须是:
const img = new Image(); img.crossOrigin = 'anonymous'; img.src = 'https://cdn.example.com/photo.jpg';
预加载时加时间戳或随机参数没用,除非也带 crossorigin
很多人以为加 ?t=123 就能绕过缓存,但若没配 crossOrigin,新请求仍是非 CORS 的,canvas 依然污染。
- 加参数只解决“缓存复用冲突”,不解决“CORS 授权缺失”
- 如果服务端没返回
Access-Control-Allow-Origin,加多少参数都没用 - 真正需要的是:服务端响应头 + 前端
crossOrigin二者同时生效
html2canvas 场景下 useCORS: true 不是万能解药
这个选项只是让 html2canvas 内部对所有 <img> 自动补 crossOrigin="anonymous",但它不能替代服务端配置。
立即学习“前端免费学习笔记(深入)”;
- 若图片服务器没返回
Access-Control-Allow-Origin,useCORS: true会导致请求直接被浏览器拦在预检(OPTIONS)阶段 - 控制台会看到
Failed to fetch或CORS header ‘Access-Control-Allow-Origin’ missing - 此时必须检查 Network 面板里图片请求的 Response Headers 是否含合法的
Access-Control-Allow-Origin
无法改服务端时,base64 是唯一可行的纯前端兜底方案
它绕过了浏览器的 CORS 校验,但仅适用于中小尺寸图片,且有内存和性能代价。
- 用
XMLHttpRequest或fetch带responseType: 'blob'请求图片 - 再用
FileReader.readAsDataURL()转成 base64 字符串 - 赋给
img.src即可安全用于 canvas —— 因为此时图片已属同源资源 - 注意:
blob请求本身仍受 CORS 限制,所以该方式只在服务端允许跨域读取(即返回了Access-Control-Allow-Origin)时才有效;否则得走后端代理
真正卡住人的从来不是怎么写那行 crossOrigin,而是没意识到:服务端响应头是否生效,决定了前端所有操作是“走通”还是“静默失败”。网络面板里点开一张图片请求,盯着 Response Headers 看一眼 Access-Control-Allow-Origin,比调十次代码都管用。



















