如何使用 http.post 在 javascript 中将图像发送到服务器并在 mongodb 中存储 base64
how to send image to server with http.post in javascript and store base64 in mongodb
我在使用 mongodb 进入客户端的 http 请求时遇到问题,在服务器端存储图像。我非常感谢帮助。我需要一个简单的示例来说明如何将图像文件作为数据添加到 http post 请求(例如 XMLhttprequest)中。比方说,我知道 servermethod 的 url。图片来源定义在
imgsrc
文件名存储在
name
我有这个 atm:
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);}
});
}
您可以通过多种方式将请求中的图像数据发送到服务器,但所有这些方式都涉及使用您希望发送的数据调用 XMLHttpRequest 对象的 send
方法作为它的论据。
send
方法将请求分派到远程服务器,并将其参数设置为该请求的主体。由于您希望服务器上有 Base64 编码的图像数据,因此您首先需要在客户端将图像文件转换为 Base64 数据。
在客户端将图像转换为 Base64 的最简单方法是将图像作为图像元素加载,将其绘制到 canvas 元素,然后获取 [=32= 的 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
属性 和您的图像文件夹路径构建图像记录的文件名,因此将其另存为 属性 记录,但我在这里保留了该功能,这将要求您在一个请求周期内保存两次记录。
我还更改了处理文件系统调用错误的方式。您从文件系统错误中返回的 'err' 已经是一个错误对象,需要由您的服务器以某种方式处理。
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);
});
})
});
}
我在使用 mongodb 进入客户端的 http 请求时遇到问题,在服务器端存储图像。我非常感谢帮助。我需要一个简单的示例来说明如何将图像文件作为数据添加到 http post 请求(例如 XMLhttprequest)中。比方说,我知道 servermethod 的 url。图片来源定义在
imgsrc
文件名存储在
name
我有这个 atm:
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);}
});
}
您可以通过多种方式将请求中的图像数据发送到服务器,但所有这些方式都涉及使用您希望发送的数据调用 XMLHttpRequest 对象的 send
方法作为它的论据。
send
方法将请求分派到远程服务器,并将其参数设置为该请求的主体。由于您希望服务器上有 Base64 编码的图像数据,因此您首先需要在客户端将图像文件转换为 Base64 数据。
在客户端将图像转换为 Base64 的最简单方法是将图像作为图像元素加载,将其绘制到 canvas 元素,然后获取 [=32= 的 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
属性 和您的图像文件夹路径构建图像记录的文件名,因此将其另存为 属性 记录,但我在这里保留了该功能,这将要求您在一个请求周期内保存两次记录。
我还更改了处理文件系统调用错误的方式。您从文件系统错误中返回的 'err' 已经是一个错误对象,需要由您的服务器以某种方式处理。
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);
});
})
});
}