我正在使用hapijs版本17.0.1。我试图在hapijs路线上使用ajax请求上传图像。这是我上传个人资料照片的AJAX代码:
var image_file_input = document.getElementById("user_profile_upload");
image_file_input.onchange = function () {
if(this.files != undefined)
{
if(this.files[0] != undefined)
{
var formData = tests.formdata ? new FormData() : null;
if (tests.formdata)
{
//alert(file)
formData.append('image_file', this.files[0]);
formData.append('userId', user_id);
formData.append('memberId', member_id);
}
$.ajax({
url: "/v1/User/uploadUserPic",
data: formData,
type: "POST",
dataType: "json",
contentType: false,
processData: false,
contentType: "multipart/form-data",
success: function(data){
console.log(data);
var errMsg = null;
var resData = null;
if(data.statusCode == 200)
{
resData = data.result;
}
else
{
alert(data.message)
}
},
error: function(error){
alert(error);
}
});
}
}
}
这是我的Hapijs路线代码:
var uploadUserPic = {
method: 'POST',
path: '/v1/Module/uploadUserPic',
config: {
description: 'Update Image For User',
tags: ['api', 'User'],
auth: 'session',
payload: {
output: 'stream',
parse: true,
allow: 'multipart/form-data'
},
validate: {
payload: {
userId : Joi.string().regex(/^[a-f\d]{24}$/i).required(),
memberId: Joi.string().required(),
image_file: Joi.object().required(),
},
failAction: FailCallBack
}
},
handler: function (request, reply) {
var resultData = null;
var error = null;
return new Promise(function (resolve) {
var multiparty = require('multiparty');
var fs = require('fs');
var form = new multiparty.Form();
form.parse(request.payload, function (err, fields, files) {
if(err)
{
error = err;
resolve();
}
else
{
var mkdirp = require('mkdirp');
var img_dir = "./files/users/";
mkdirp(img_dir, function (err) {
if (err)
{
error = err;
console.error(err);
resolve();
}
else
{
var oldpath = files.image_file.path;
var newpath = "./files/users/"+requestPayload.userId+".png";
fs.rename(oldpath, newpath, function (err) {
if(err)
{
error = err;
}
resolve();
});
}
});
}
});
}).then(function (err, result) {
if(err) return sendError(err);
if(error) return sendError(error)
return {
"statusCode": 200,
"success": true
};
});
}
}
上面的代码在cannot read property 'content-length' of undefined
form.parse(request.payload, function (err, fields, files) {});
如果我做错了,请告诉我。如果我使用我用php编写的anohter url替换ajax请求中的url,那么它可以正常工作。这意味着我的hapijs / nodejs代码出了问题。
答案 0 :(得分:0)
关于如何在Hapi.js中处理文件上传的好文章(用版本16编写)https://scotch.io/bar-talk/handling-file-uploads-with-hapi-js
由于您使用的是payload.parse = true
,因此我没有看到您必须使用multiparty
的特定原因。我有以下工作代码,可以将从客户端上传的文件(任何类型)保存到服务器上的上传目录中(请不要直接在生产中使用,因为没有卫生设施)
{
path: '/upload',
method: 'POST',
config: {
payload: {
output: 'stream',
parse: true,
allow: 'multipart/form-data'
},
validate: {
payload: {
files: Joi.array().single()
}
}
},
handler: function(request) {
const p = request.payload, files = p.files
if(files) {
console.log(`${files.length} files`)
files.forEach(async file => {
const filename= file.hapi.filename
console.log(`Saving ${filename} to ./uploads`)
const out = fs.createWriteStream(`./uploads/${filename}`)
await file.pipe(out)
})
}
return {result: 'ok'}
}
}
您可以使用以下curl命令来测试
curl http://localhost:8080/upload -F 'files=@/path/to/a/note.txt' -F 'files=@/path/to/test.png' -vvv
您的代码存在一些问题。首先在$.ajax
电话中,您已指定contentType
两次,但它不是语法错误,但它不会像这样编写代码。其次,.then()块内的函数签名不正确。你正在混合Promise和回调的想法。我不认为会触发以下行
if(err) return sendError(err);
最后一件小事,你说你使用的是Hapi 17但是基于处理函数的签名
handler: function (request, reply) {
...
似乎你没有完全登上Hapi17,因为新的签名是
handler: function (request, h) {
并且不仅仅是reply
重命名为h
。