仅当预加载图像时 canvas 才会出现 CORS 问题
CORS issue with canvas only when image is preloaded
我的问题只有在加载的图像预加载到其他地方时才会出现。例如,当我在某处使用带有 src
属性的 <img>
标签时。
看看这段代码:
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;" ></canvas>
<img src="https://local-spaces.fra1.digitaloceanspaces.com/test.jpg" width="50"/>
<button onclick="show()">Load Canvas Picture</button>
<script>
function show() {
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function(){
ctx.drawImage(img,0,0, 300, 150);
};
img.src = "https://local-spaces.fra1.digitaloceanspaces.com/test.jpg"
}
</script>
注意:如果您在 canvas 中正确看到图像,请缓存+硬重新加载您的浏览器以查看错误。
如果您单击该按钮并打开您的控制台,您将看到您得到 CORS-error:
Access to image at
'https://local-spaces.fra1.digitaloceanspaces.com/test.jpg' from
origin 'null' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
现在让我们看下一个例子,看看它在没有预加载图像的情况下工作:https://jsfiddle.net/akzxp9vs/
注意:要使此示例正常运行,删除缓存并重新加载浏览器非常重要。
只有这样你才能看到正确的 header 响应正在回馈。
有什么办法吗?
图片在Digital Ocean的S3 Cloud上,叫做Spaces。图像本身设置为 public 并且 CORS 设置设置为:
浏览器需要知道在发出 HTTP 请求时检查 CORS 权限(即包含 Origin
header 等)。
当您创建新的 Image
object 时,它会使用来自 <img>
元素的缓存数据。
向现有 <img>
元素添加 crossorigin
属性或完全删除该 <img>
元素。
我找到了解决问题的更好方法。 @Quentin 的解决方案基本上是正确的,但它不可行。我试图更新所有 <img>
-标签,但是在我的页面中我有许多包也在使用 <img>
-标签。
例如传单。它类似于 Google 地图,但带有开放式街道地图。您只是无法控制在自定义图标中设置 crossorigin
等属性。
所以必须有另一种解决方案。使用起来感觉很糟糕,但它确实有效。
const src = new URL(imgUrl);
src.searchParams.append('cors', Date.now());
return src.href;
此代码附加到您的 URL 查询参数并强制 Chrome 重新加载图像而不缓存。
我的问题只有在加载的图像预加载到其他地方时才会出现。例如,当我在某处使用带有 src
属性的 <img>
标签时。
看看这段代码:
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;" ></canvas>
<img src="https://local-spaces.fra1.digitaloceanspaces.com/test.jpg" width="50"/>
<button onclick="show()">Load Canvas Picture</button>
<script>
function show() {
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function(){
ctx.drawImage(img,0,0, 300, 150);
};
img.src = "https://local-spaces.fra1.digitaloceanspaces.com/test.jpg"
}
</script>
注意:如果您在 canvas 中正确看到图像,请缓存+硬重新加载您的浏览器以查看错误。
如果您单击该按钮并打开您的控制台,您将看到您得到 CORS-error:
Access to image at 'https://local-spaces.fra1.digitaloceanspaces.com/test.jpg' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
现在让我们看下一个例子,看看它在没有预加载图像的情况下工作:https://jsfiddle.net/akzxp9vs/
注意:要使此示例正常运行,删除缓存并重新加载浏览器非常重要。
只有这样你才能看到正确的 header 响应正在回馈。
有什么办法吗?
图片在Digital Ocean的S3 Cloud上,叫做Spaces。图像本身设置为 public 并且 CORS 设置设置为:
浏览器需要知道在发出 HTTP 请求时检查 CORS 权限(即包含 Origin
header 等)。
当您创建新的 Image
object 时,它会使用来自 <img>
元素的缓存数据。
向现有 <img>
元素添加 crossorigin
属性或完全删除该 <img>
元素。
我找到了解决问题的更好方法。 @Quentin 的解决方案基本上是正确的,但它不可行。我试图更新所有 <img>
-标签,但是在我的页面中我有许多包也在使用 <img>
-标签。
例如传单。它类似于 Google 地图,但带有开放式街道地图。您只是无法控制在自定义图标中设置 crossorigin
等属性。
所以必须有另一种解决方案。使用起来感觉很糟糕,但它确实有效。
const src = new URL(imgUrl);
src.searchParams.append('cors', Date.now());
return src.href;
此代码附加到您的 URL 查询参数并强制 Chrome 重新加载图像而不缓存。