我在网页上有类似于在Facebook上发布网址的功能。用户输入URL并加载图像和描述。然后,用户可以选择发布该图像和描述(一切正常)。当用户尝试发布图像时,行为应该是:Javascript将获取图像src,将其加载到画布,调整大小,动态添加到表单(以及描述),然后发布。结果应该是图像和描述被发送到我的服务器进行处理和保存。如果我有一个本地图像源,所有这一切都很好。如果我有远程图像源,它会失败。我的理由是我有一个CORS问题,但我不确定如何解决它。以下是注释中包含错误的函数。
function postNewsAuto() {
var MAX_WIDTH = 400;
var MAX_HEIGHT = 400;
var img = document.createElement("img");
/*
* the src on the next line contains an image from another site
*/
img.src = $('#auto-news-image').attr('src');
img.onload = function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
/*
* this next line fails with the error:
* Security Error: The operation is insecure
* presumably a CORS issue
*/
var dataurl = canvas.toDataURL("image/jpeg");
var blob = dataURItoBlob(dataurl);
var fd = new FormData(document.forms[0]);
fd.append("url", $('#auto-news-url').text());
fd.append("description", $('#auto-news-url').attrib('href'));
fd.append("image", blob);
/*
* at this point in the code I post
* the form via XMLHttpRequest()
* this code also works, I removed it for brevity
*/
};
}
我意识到一个简单的方法是存储图像位置而不是图像本身,然后根据需要提供它。但是我想存储它以避免链接断开,因为远程图像将无法控制。真正的问题是,如何从远程大小获取图像并将其保存到我的服务器?所以把所有调整大小和发布(我知道该怎么做)放在一边,在最基本的层面上,问题很简单,我如何从远程站点在我的服务器上复制一个图像?
这里引用了另一个函数dataURItoBlob()。此功能也可以正常工作,但我已将其发布以供参考。
function dataURItoBlob(dataURI) {
'use strict';
var byteString, mimestring;
if (dataURI.split(',')[0].indexOf('base64') !== -1) {
byteString = atob(dataURI.split(',')[1]);
} else {
byteString = decodeURI(dataURI.split(',')[1]);
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0];
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i);
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
答案 0 :(得分:2)
您有两种选择适合您的情况。
在远程网站上设置CORS标头。但是这个解决方案对你来说是错误的,因为你无法控制每个网站,并要求他们为你设置CORS标题。
您需要编写服务器代理中间件(Python,Node等),它将发送请求任何远程网站并返回内容。此解决方案更好,因为您自己的服务器不会遇到CORS问题。