【问题标题】:how to send image to server with http.post in javascript and store base64 in mongodb如何在javascript中使用http.post将图像发送到服务器并将base64存储在mongodb中
【发布时间】:2016-04-30 13:12:55
【问题描述】:

我在客户端使用 mongodb 在服务器端存储图像时遇到了 http 请求。我非常感谢帮助。我需要一个简单的示例来说明如何将图像文件作为数据添加到诸如 XMLhttprequest 之类的 http post 请求中。可以说,我知道服务器方法的 url。图片的来源在

中定义
imgsrc

文件名存储在

name

我有这个自动取款机:

var http = new XMLHttpRequest();
httpPost.onreadystatechange = function(err) {
        if (httpPost.readyState == 4 && httpPost.status == 200){
            console.log(httpPost.responseText);
        } else {
            console.log(err);
        }
    }
var  path = "http://127.0.0.1:8000/uploadImage/"+name;
httpPost.open("POST", path, true);
// I guess I have to add the imagedata into the httpPost here, but i dont know how
httpPost.send(null);

然后在路径的服务器端,会调用下面的方法,我想把base64编码的图片的url存储到mongodb中。如何从 httpPost 访问图像?

function postNewImageType(req, res, next){
    var newImageTypeData = {
         name: req.params.name,
         image: "placeholder.png"
    }
    var data = // how to access the image?
    var imageBuffer = decodeBase64Image(data);
    fs.writeFile(cfg.imageFolger+newImageTypeData._id+'.jpeg', imageBuffer.data, function(err){
        if (err) return new Error(err);
        newImageTypeData.set({image:newImageTypeData._id+'.jpeg'});
        var image = new ImageType(newImageData);

    });
    imagetype.save(function (err) {
        if (error) {return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)));}
        else { res.send(201, imagetype);}
    });   
}

【问题讨论】:

    标签: javascript http-headers xmlhttprequest base64


    【解决方案1】:

    您可以通过多种方式将请求中的图像数据发送到服务器,但所有这些都需要调用 XMLHttpRequest 对象的 send 方法,并将您希望发送的数据作为其参数。

    send 方法将请求分派到远程服务器,并将其参数设置为该请求的主体。由于您希望在服务器上使用 Base64 编码的图像数据,因此您首先需要在客户端将图像文件转换为 Base64 数据。

    在客户端将图像转换为 Base64 的最简单方法是将图像加载为图像元素,将其绘制到画布元素,然后获取画布图像数据的 Base64 表示。

    这可能类似于以下内容(假设原始图像的 URL 存储在名为 imgsrc 的变量中,而所需的名称存储在 name 中,如上所述):

    // This function accepts three arguments, the URL of the image to be 
    // converted, the mime type of the Base64 image to be output, and a 
    // callback function that will be called with the data URL as its argument 
    // once processing is complete
    
    var convertToBase64 = function(url, imagetype, callback){
    
        var img = document.createElement('IMG'),
            canvas = document.createElement('CANVAS'),
            ctx = canvas.getContext('2d'),
            data = '';
    
        // Set the crossOrigin property of the image element to 'Anonymous',
        // allowing us to load images from other domains so long as that domain 
        // has cross-origin headers properly set
    
        img.crossOrigin = 'Anonymous'
    
        // Because image loading is asynchronous, we define an event listening function that will be called when the image has been loaded
        img.onLoad = function(){
            // When the image is loaded, this function is called with the image object as its context or 'this' value
            canvas.height = this.height;
            canvas.width = this.width;
            ctx.drawImage(this, 0, 0);
            data = canvas.toDataURL(imagetype);
            callback(data);
        };
    
        // We set the source of the image tag to start loading its data. We define 
        // the event listener first, so that if the image has already been loaded 
        // on the page or is cached the event listener will still fire
    
        img.src = url;
    };
    
    // Here we define the function that will send the request to the server. 
    // It will accept the image name, and the base64 data as arguments
    
    var sendBase64ToServer = function(name, base64){
        var httpPost = new XMLHttpRequest(),
            path = "http://127.0.0.1:8000/uploadImage/" + name,
            data = JSON.stringify({image: base64});
        httpPost.onreadystatechange = function(err) {
                if (httpPost.readyState == 4 && httpPost.status == 200){
                    console.log(httpPost.responseText);
                } else {
                    console.log(err);
                }
            };
        // Set the content type of the request to json since that's what's being sent
        httpPost.setHeader('Content-Type', 'application/json');
        httpPost.open("POST", path, true);
        httpPost.send(data);
    };
    
    // This wrapper function will accept the name of the image, the url, and the 
    // image type and perform the request
    
    var uploadImage = function(src, name, type){
        convertToBase64(src, type, function(data){
            sendBase64ToServer(name, data);
        });
    };
    
    // Call the function with the provided values. The mime type could also be png
    // or webp
    
    uploadImage(imgsrc, name, 'image/jpeg')
    

    当您的服务器收到请求时,请求正文将包含 JSON 字符串,其中包含您的 Base64 图像。由于您尚未提供用于 Mongo 的服务器框架或数据库驱动程序,因此我已经修改了您的代码,假设您正在使用 Express 和 Mongoose,并且已经在应用程序中定义了 ImageType 模型。

    由于您始终可以从其_id 属性和图像文件夹路径构造图像记录的文件名,因此将其保存为记录上的属性不一定有意义,但我保留了它此处的功能,这将要求您在一个请求周期内保存您的记录两次。

    我还更改了处理文件系统调用中的任何错误的方式。您从文件系统错误中返回的“错误”已经是一个错误对象,并且需要由您的服务器以某种方式处理。

    function postNewImageType(req, res, next){
        var json = JSON.parse(req.body),
            newImageTypeData = {
                name: json.name,
                image: "placeholder.png"
            },
            imageBuffer = decodeBase64Image(data),
            newImageType = new ImageType(newImageTypeData);
    
        //First we save the image to Mongo to get an id
    
        newImageType.save(function(err){
            if(err) return next(new restify.InvalidArgumentError(JSON.stringify(err.errors)));
            var fileName = cfg.imageFolder + newImageType._id + '.jpeg';
    
            fs.writeFile(fileName, imageBuffer.data, function(err){
                //Handle error in next middleware function somehow
                if (err) return next(err);
                newImageType.set({image: 'filename.png'});
                newImageType.save(function(err){
                    if (err) return next(new restify.InvalidArgumentError(JSON.stringify(err.errors)));
                    res.send(201, imagetype);
                });
            })
        });
    }
    

    【讨论】:

    • 非常感谢!这个 rly 帮助我最终发送并保存了图像!代码中有一些小错误,但我可以在您的帮助下完成所有工作。 +1,因为我没有对我使用的框架给出足够的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多