当前位置: 代码迷 >> JavaScript >> 如何从另一个站点加载图像并保存在我的站点中? 碰到CORS问题(我认为)
  详细解决方案

如何从另一个站点加载图像并保存在我的站点中? 碰到CORS问题(我认为)

热度:37   发布时间:2023-06-05 14:16:57.0

我在网页上具有类似于在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});
}

您有两种适合您情况的选择。

不好的解决方案

在远程网站上设置CORS标头。 但是,该解决方案对您来说是错误的,因为您无法控制那里的每个网站,都无法要求他们为您设置CORS标头。

好的解决方案

您需要编写服务器代理中间件(Python,Node等),该中间件将向任何远程网站发送请求并返回内容。 此解决方案更好,因为您自己的服务器不会遇到CORS问题。