html <img src="..."/>有效但JS Image加载导致CORS错误

时间:2017-03-24 13:22:57

标签: javascript html cors hotlinking

我想在js + jquery中创建图片编辑器。在第一步,我要求用户提供图像网址。但是当我尝试在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标签加载它)并将其转换为base64 url​​,避免CORS问题?

https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg

2 个答案:

答案 0 :(得分:4)

我试图找到自己的解决方案(JS ES6),但只能找到部分解决方案。我们可以将img从无CORS支持src加载到画布中,但是浏览器可以将空格转换为&#39; taint mode&#39;这不允许我们拨打toDataURL(以及对内容的任何其他访问权限)。

因此,克服这一障碍的唯一方法是创建代理服务器(例如在PHP中),它将具有CORS&#39; on&#39;它将下载给定网址的图片并发送回我们在JS的应用程序。我找到了一些免费的服务器https://cors-anywhere.herokuapp.com,我们可以用它来开发测试。下面是完整的功能代码,它从给定的图像URL返回dataUri:

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);
    };
}

我们可以通过这个来调用它(es6):

let url='https://static.pexels.com/photos/87293/pexels-photo-87293.jpeg';
this.loadImgAsBase64(url, (dataURL) => { console.log('imgData:',dataURL) });

多数人都是:)(我只在Chrome上测试过它)

答案 1 :(得分:-1)

避免CORS的唯一方法是进行更改以避免跨域共享,至少让浏览器认为它是跨域的。

或者,您必须修改服务器以支持CORS。