Html <img src=...> 有效但 JS 图像加载导致 CORS 错误
Html <img src=...> works but JS Image loading cause CORS error
我想在js+中创建图片编辑器jquery。在第一步,我要求用户提供图像 url。但是当我尝试在 JS 中加载图像数据(生成 base64 图像 uri)时遇到问题。我在控制台中收到错误消息:… has beeb blocked by CORS policy: Access-Control-Allow-Origin …
。但我想知道为什么?例如,如果在 html 文件中创建(图像盗链):
<img src="https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg" />
浏览器加载图像没有任何 CORS 问题!这是我的 JS 代码,对于同一张图片抛出 CORS 问题:
function downloadFile(url) {
console.log({url});
var img = new Image();
img.onload = function() {
console.log('ok');
// never execute because cors error
// … make base64 uri with image data needed for further processing
};
img.crossOrigin = "Anonymous";
img.src = url;
}
所以问题是 - 如何强制 JS 加载图像(如 html-tag 加载它)并将其转换为 base64 url 避免 CORS 问题?
https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg
我尝试自己找到解决方案(JS ES6),但只找到了部分。我们能够从无 CORS 支持的 src 加载 img 到 canvas,但浏览器将 cavnas 切换到 'taint mode',这不允许我们调用 toDataURL
(以及任何其他对内容的访问)。
function loadImgAsBase64(url, callback) {
let canvas = document.createElement('CANVAS');
let img = document.createElement('img');
//img.setAttribute('crossorigin', 'anonymous');
img.src = url;
img.onload = () => {
canvas.height = img.height;
canvas.width = img.width;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
canvas = null;
callback(dataURL);
};
}
let url = 'http://lorempixel.com/500/150/sports/9/';
this.loadImgAsBase64(url, (dataURL) => {
msg.innerText = dataURL.slice(0,50)+'...';
});
IMAGE DATA: loading...<br>
<div id="msg"></div>
所以克服这个障碍的唯一方法是创建代理服务器(例如在 PHP 中),它将具有 CORS 'on' 并且它将下载给定 url 的图像并发回到我们的 JS 应用程序。我找到了一些免费服务器 https://cors-anywhere.herokuapp.com,我们可以在开发和测试中使用它。下面是完整的功能代码,其中 return 来自给定图像 url 的 dataUri:
function loadImgAsBase64(url, callback) {
let canvas = document.createElement('CANVAS');
let img = document.createElement('img');
img.setAttribute('crossorigin', 'anonymous');
img.src = 'https://cors-anywhere.herokuapp.com/' + url;
img.onload = () => {
canvas.height = img.height;
canvas.width = img.width;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
canvas = null;
callback(dataURL);
};
}
let url = 'http://lorempixel.com/500/150/sports/9/';
this.loadImgAsBase64(url, (dataURL) => {
msg.innerText = dataURL.slice(0,50)+'...';
// show pic
document.body.innerHTML += `<img src="${dataURL}">`
});
IMAGE DATA Loading...<br>
<div id="msg"></div>
就这些:)(我在 chrome、firefox 和 safari 上测试过)
唯一避免CORS的方法就是修改避免跨域共享,至少让浏览器认为是跨域。
或者,您必须修改服务器以支持 CORS。
我有一个类似的问题,当我将查询参数作为图像的一部分传递时,我的问题得到了解决 url。
我想在js+中创建图片编辑器jquery。在第一步,我要求用户提供图像 url。但是当我尝试在 JS 中加载图像数据(生成 base64 图像 uri)时遇到问题。我在控制台中收到错误消息:… has beeb blocked by CORS policy: Access-Control-Allow-Origin …
。但我想知道为什么?例如,如果在 html 文件中创建(图像盗链):
<img src="https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg" />
浏览器加载图像没有任何 CORS 问题!这是我的 JS 代码,对于同一张图片抛出 CORS 问题:
function downloadFile(url) {
console.log({url});
var img = new Image();
img.onload = function() {
console.log('ok');
// never execute because cors error
// … make base64 uri with image data needed for further processing
};
img.crossOrigin = "Anonymous";
img.src = url;
}
所以问题是 - 如何强制 JS 加载图像(如 html-tag 加载它)并将其转换为 base64 url 避免 CORS 问题?
https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg
我尝试自己找到解决方案(JS ES6),但只找到了部分。我们能够从无 CORS 支持的 src 加载 img 到 canvas,但浏览器将 cavnas 切换到 'taint mode',这不允许我们调用 toDataURL
(以及任何其他对内容的访问)。
function loadImgAsBase64(url, callback) {
let canvas = document.createElement('CANVAS');
let img = document.createElement('img');
//img.setAttribute('crossorigin', 'anonymous');
img.src = url;
img.onload = () => {
canvas.height = img.height;
canvas.width = img.width;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
canvas = null;
callback(dataURL);
};
}
let url = 'http://lorempixel.com/500/150/sports/9/';
this.loadImgAsBase64(url, (dataURL) => {
msg.innerText = dataURL.slice(0,50)+'...';
});
IMAGE DATA: loading...<br>
<div id="msg"></div>
所以克服这个障碍的唯一方法是创建代理服务器(例如在 PHP 中),它将具有 CORS 'on' 并且它将下载给定 url 的图像并发回到我们的 JS 应用程序。我找到了一些免费服务器 https://cors-anywhere.herokuapp.com,我们可以在开发和测试中使用它。下面是完整的功能代码,其中 return 来自给定图像 url 的 dataUri:
function loadImgAsBase64(url, callback) {
let canvas = document.createElement('CANVAS');
let img = document.createElement('img');
img.setAttribute('crossorigin', 'anonymous');
img.src = 'https://cors-anywhere.herokuapp.com/' + url;
img.onload = () => {
canvas.height = img.height;
canvas.width = img.width;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
let dataURL = canvas.toDataURL('image/png');
canvas = null;
callback(dataURL);
};
}
let url = 'http://lorempixel.com/500/150/sports/9/';
this.loadImgAsBase64(url, (dataURL) => {
msg.innerText = dataURL.slice(0,50)+'...';
// show pic
document.body.innerHTML += `<img src="${dataURL}">`
});
IMAGE DATA Loading...<br>
<div id="msg"></div>
就这些:)(我在 chrome、firefox 和 safari 上测试过)
唯一避免CORS的方法就是修改避免跨域共享,至少让浏览器认为是跨域。
或者,您必须修改服务器以支持 CORS。
我有一个类似的问题,当我将查询参数作为图像的一部分传递时,我的问题得到了解决 url。