javascript - Html <img src=...> 有效但 JS 图像加载导致 CORS 错误

标签 javascript html cors hotlinking

我想在js+jquery中创建图片编辑器。在第一步,我要求用户提供图片 url。但是当我尝试在 JS 中加载图像数据(生成 base64 图像 uri)时遇到问题。我在控制台中收到错误消息:... beeb 已被 CORS 策略阻止: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

最佳答案

我尝试自己找到解决方案(JS ES6),但只找到了部分。我们能够将 img 从无 CORS 支持的 src 加载到 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,它将下载给定 url 的图像并发送回我们在 JS 中的应用程序。我找到了一些免费服务器 https://cors-anywhere.herokuapp.com我们可以在开发和测试中使用它。下面是从给定图像 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 上测试过)

关于javascript - Html <img src=...> 有效但 JS 图像加载导致 CORS 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43000648/

相关文章:

android - 从 Android web View 的 HTML 页面中包含的 js 文件进行的 ajax 调用是否面临 CORS 问题?

javascript - AJAX 请求从 HTTPS 页面到 HTTP Url

javascript - JavaScript 未捕获类型错误 : Cannot set property 'value' of null,

javascript - 模糊事件不会在 IE7 和 IE6 中触发

html - CSS 在 IE11 中有效,但在 IE8 中无效

javascript - 如何检测当前的iframe url?

java - Spring boot 中的 CORS 策略冲突

javascript - 准备好的查询的 Node.js PostgreSQL 单引号问题

多个 HTML 背景颜色的 Javascript 变量

javascript - 将数据从 GoogleChart 保存到 CSV