Chr*_*ris 8 javascript base64 dom canvas cors
我需要根据其 URL 将远程图像转换为 base64,但我遇到了 CORS 错误并且不确定如何解决。
我遵循了关于这个问题的一些解决方案:How to convert image into base64 string using javascript
我的示例图片是:https : //blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg
方法一(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)} );
Run Code Online (Sandbox Code Playgroud)
这会产生错误:
XMLHttpRequest 无法加载 https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问源“ http://stackoverflow.com ”。
方法 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)} );
Run Code Online (Sandbox Code Playgroud)
尝试加载图像时产生类似的错误:
从源 ' http://stackoverflow.com '访问“ https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg ”上的图像已被 CORS 策略阻止:无“访问” -Control-Allow-Origin' 标头存在于请求的资源上。因此,不允许访问源“ http://stackoverflow.com ”。
还尝试过:
img.crossOrigin = 'anonymous';
Run Code Online (Sandbox Code Playgroud)
并得到了相同的结果。
方法三(Canvas 使用 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';
Run Code Online (Sandbox Code Playgroud)
这种方式至少加载图像,但在调用 toDataURL 时失败:
未捕获的 DOMException:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布。在 HTMLImageElement.img.onload (:9:22)
顺便说一句,我不确定 CORS 政策到底在保护什么。假设存在某种可能触发漏洞利用的恶意负载。我们仍然在 DOM 中加载和显示图像,为什么我们会信任由同一端点设置的 CORS 标头?
有谁知道这个问题的任何解决方案?
谢谢你的帮助。
sid*_*ker 10
您可以通过CORS 代理提出请求来绕过 CORS 限制,如下所示:
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)} );
Run Code Online (Sandbox Code Playgroud)
代理将请求发送到targetUrl,然后在获得响应后,添加Access-Control-Allow-Origin响应头和所需的任何其他 CORS 响应头,最后将其传递回您的请求代码。
Access-Control-Allow-Origin添加了标头的响应是浏览器看到的,因此浏览器让您的前端代码访问响应,并且您不会收到任何 CORS 错误。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS解释了正在发生的事情导致需要配置请求的服务器,以便它发送必要的 CORS 标头,或者否则在中间放置一个代理来为您添加 CORS 标头(如上所述)。
而不是像本答案中的代码片段那样使用第三方代理,您可以使用https://github.com/Rob--W/cors-anywhere/或类似的代码轻松设置自己的 CORS 代理.
顺便说一句,我不确定 CORS 政策到底在保护什么。
在这种特殊情况下它不是真正的保护反对所有的东西,因为你可以得到https://blog.xenproject.org/wp-content/uploads/2014/10/Testing.jpg使用任何服务器端编程语言或公共代理curl或其他。
https://blog.xenproject.org的维护者应该正确地将他们的服务器配置为发送一个Access-Control-Allow-Origin响应头,告诉浏览器允许从任何来源获取他们的内容。但既然他们没有,你只需要使用代理。
CORS 限制真正有用的唯一情况是在 Intranet 上运行或以其他方式在某种防火墙后面运行的资源。因为在 Intranet/防火墙的情况下,让任意 Web 应用程序以与 Intranet/防火墙内的用户相同的权限运行并不是一个好主意。
| 归档时间: |
|
| 查看次数: |
9172 次 |
| 最近记录: |