尝试将远程映像转换为base64数据时发生CORS错误 [英] CORS errors trying to convert remote image to base64 data

查看:113
本文介绍了尝试将远程映像转换为base64数据时发生CORS错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要根据其URL将远程映像转换为base64,但是我遇到了CORS错误,不确定如何解决.

I need to convert a remote image into base64 given its URL, but I am running in to CORS errors and not sure how to work around.

我已经遵循了有关此问题的一些解决方案:如何使用javascript将图片转换为base64字符串

I've followed some of the solutions on this question: How to convert image into base64 string using javascript

我的示例图片是: https://blog.xenproject .org/wp-content/uploads/2014/10/Testing.jpg

方法1(FileReader):

function toDataUrl(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
      callback(reader.result);
    }
    reader.readAsDataURL(xhr.response);
  };
  xhr.open('GET', url);
  xhr.responseType = 'blob';
  xhr.send();
}

toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );

这会产生错误:

XMLHttpRequest无法加载 https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg .不 请求中存在"Access-Control-Allow-Origin"标头 资源.因此,不允许使用来源" http://stackoverflow.com " 访问.

XMLHttpRequest cannot load https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://stackoverflow.com' is therefore not allowed access.

方法2(画布)

function toDataUrl(src, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'use-credentials';
  img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL);
  };
  img.src = src;
  if (img.complete || img.complete === undefined) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
  }
}
toDataUrl('https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg', function(data) { console.log(data)} );

在尝试加载图像时产生类似的错误:

Produces a similar error when trying to load the image:

在以下位置访问图像 ' https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg ' 来自来源" http://stackoverflow.com "的内容已被CORS阻止 策略: 要求的资源.因此,来源' http://stackoverflow.com '不是 允许访问.

Access to Image at 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg' from origin 'http://stackoverflow.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://stackoverflow.com' is therefore not allowed access.

也尝试过:

img.crossOrigin = 'anonymous';

得到相同的结果.

方法3(使用img元素画布):

img = document.createElement('img');
img.onload = function() {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height;
    canvas.width = this.width;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL('image/jpg');
    console.log(dataURL);
};
img.src = 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg';

这种方式至少可以加载图像,但无法通过以下方式调用toDataURL:

This way at least loads the image but fails on calling toDataURL with:

未捕获的DOMException:无法在上执行"toDataURL" 'HTMLCanvasElement':可能无法导出污染的画布. 在HTMLImageElement.img.onload(:9:22)

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at HTMLImageElement.img.onload (:9:22)

顺便说一句,我不确定CORS政策到底在保护什么.假设存在某种可能触发漏洞利用的恶意有效载荷.我们仍然在DOM中加载并显示图像,为什么我们会信任由同一端点设置的CORS标头?

As an aside, I'm not sure exactly what the CORS policy is protecting against here. Suppose there is some kind of malicious payload that could trigger an exploit. We still load and display the image in the DOM and why would we trust CORS headers set by the same endpoint?

有人知道这个问题有什么解决办法吗?

Does anyone know of any solutions to this problem?

感谢您的帮助.

推荐答案

您可以通过

You can get around the CORS restriction by making your request through a CORS proxy, like this:

var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
   targetUrl = 'https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg'
toDataUrl(proxyUrl + targetUrl,
  function(data) { console.log(data)} );

代理将请求发送到targetUrl,然后在返回响应之后,添加Access-Control-Allow-Origin响应标头&任何其他所需的CORS响应标头,最后将其传递回您的请求代码.

The proxy sends the request to targetUrl, then after it gets the response back for that, adds the Access-Control-Allow-Origin response header & any other CORS response headers needed, and finally then passes that back to your requesting code.

添加了Access-Control-Allow-Origin标头的响应就是浏览器看到的内容,因此浏览器允许您的前端代码访问响应,而不会出现任何CORS错误.

That response with the Access-Control-Allow-Origin header added is what the browser sees, so the browser lets your frontend code access the response and you don’t get any CORS error.

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS 解释了发生了什么,导致需要配置请求的服务器,以使其发送必要的CORS标头,或者在两者之间放置一个代理以添加为您提供的CORS标头(如上所述).

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explains what’s happening that leads to the need to either configure the server the request is being made to such that it sends the necessary CORS headers, or else put a proxy in between to add the CORS headers for you (as described above).

您可以使用

顺便说一句,我不确定CORS政策到底在保护什么.

As an aside, I'm not sure exactly what the CORS policy is protecting against here.

在这种特殊情况下,它根本无法防止任何攻击,因为您可以访问 https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg 使用任何服务器端编程语言或公共代理或curl或随便.

In this particular case it’s not really protecting against anything at all, because you can get to https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg using any server-side programming language or a public proxy or curl or whatever.

https://blog.xenproject.org 的维护者应该正确地将自己的服务器配置为发送Access-Control-Allow-Origin响应标头,告诉浏览器允许从任何来源获取其内容.但是由于它们没有,您只需要使用代理即可.

The maintainers of https://blog.xenproject.org rightly should be have their server configured themselves to send a Access-Control-Allow-Origin response header that tells browsers to allow fetching their content from any origin. But since they don’t, you just have to use a proxy.

CORS限制真正有用的唯一情况是在Intranet上或在某种类型的防火墙后面运行的资源.因为在这种Intranet/防火墙情况下,让任意Web应用程序以与Intranet/防火墙内部的用户相同的权限运行并不是一个好主意.

The only case where CORS restrictions are really useful is for resources running on an intranet or otherwise behind some kind of firewall. Because in that intranet/firewall case, it’s not a good idea to have arbitrary web apps running with the same authority as the user inside the intranet/firewall.

这篇关于尝试将远程映像转换为base64数据时发生CORS错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆