需要权限:ohos.permission.INTERNET
1.nodejs自定义书写上传后端接口
传输过来的数据放在files?.image下
router.post('/upload',(req, res) => {
var form = new multiparty.Form();
form.uploadDir='public/images/uploads'; //上传图片保存的地址(目录必须存在)
form.parse(req, function(err, fields, files) {// 1、fields:获取表单的数据 2、files:图片上传成功返回的信息
console.log(files,fields)
const fileurl = Date.now()+ files?.image[0]?.originalFilename;
let newPath = form.uploadDir + '/' +fileurl
fs.renameSync(files.image[0].path,newPath);
let imgUrl = myUrl.myUrl+'/images/uploads/' +fileurl
res.send({
code: '200',
message: '数据上传成功',
data:imgUrl
})
})
})
2,在jq中请求(new FormData())
var fileImg;
//读取图片
function fileUpload(_this) {
var fileReader = new FileReader();//创建文件读取对象
fileImg = _this.files[0];//获取file组件中的文件
}
//上传图片
function uploadPictures() {
var formData = new FormData();
//图片
if (fileImg != null) {
formData.append("image", fileImg);
}
$.ajax({
url: 'http://localhost:3333/api/img/upload',
type: 'post',
data: formData,
processData: false,
contentType: false,
success: function (res) {
// var res = JSON.parse(res);
console.log('upload success', res);
// $('.img').attr('src', res.path);
debugger
},
error: function (err) {
console.log('upload error', err);
console.log(err);
}
});
}
3.对比在鸿蒙arkts请求如下 -试用相册的场景
1.假设数据来源于相册,以下是获取相册的数据,photoSelectResult.photoUris[0]是一个目录的路径, 但是不是context.cacheDir的路径,
试用下载必须要在cacheDir目录下面
async selectPhoto() {
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.maxSelectNumber = 1;
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
let textInfo: photoAccessHelper.TextContextInfo = {
text: '人像'
};
let recommendationOptions: photoAccessHelper.RecommendationOptions = {
textContextInfo: textInfo
};
PhotoSelectOptions.recommendationOptions =
recommendationOptions; // 将推荐参数赋值给 photoSelectOptions.recommendationOptions
let photoPicker = new photoAccessHelper.PhotoViewPicker();
let photoSelectResult = await photoPicker.select(PhotoSelectOptions)
if (photoSelectResult.photoUris.length == 1) {
this.uploadFile(photoSelectResult.photoUris[0])
}
} catch (error) {
let err: BusinessError = error as BusinessError;
}
}
2.因为必须是cacheDir目录,从相册拿到的的图片就复制一份存在cacheDir
// 提取文件扩展名的函数
getFileExtension(fileName: string): string {
const lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex !== -1 && lastDotIndex < fileName.length - 1) {
return fileName.slice(lastDotIndex + 1);
}
return '';
}
。。。。。
console.log('photoUris', photoUris)
const extensionName = this.getFileExtension(photoUris) // 后缀名
console.log('文件扩展名是:', extensionName);
const cacheDir = context.cacheDir; // 缓存根目录
const names = 'phone' + Date.now() + '.' + extensionName // 文件名
const cacheF = cacheDir + '/' + names // 缓存目录路径
let file: fileIo.File | undefined;
file = fileIo.openSync(photoUris, fileIo.OpenMode.READ_ONLY); // 打开现有的文件
fileIo.copyFileSync(file.fd, cacheF); //复制一下到缓存文件
fileIo.closeSync(file); // 关闭
console.log('文件扩展名是:', extensionName, '----', names);
3。知道了cacheDir目录就组装参数
let files: Array<request.File> = [
//uri前缀internal://cache 对应cacheDir目录
{
filename: names,
name: 'image', // 必须是image,因为接口拿的数据就是这个的第0项
uri: 'internal://cache/' + names,
type: extensionName
}
]
let data: Array = [{ name: 'name', value: 'value' }];
let uploadConfig: request.UploadConfig = {
url: 'http://xxxxxxxxxxxxxxxx/api/img/upload',
header: {
// 根据项目添加
},
method: 'POST',
files: files,
data: data,
}
// 将本地应用文件上传至网络服务器
try {
request.uploadFile(context, uploadConfig)
.then((uploadTask: request.UploadTask) => {
let headerCallback = (value: object) => {
let str = JSON.stringify(value)
console.log("http:success:", JSON.stringify(rstr ))
};
uploadTask.on('headerReceive', headerCallback);
})
.catch((err: BusinessError) => {
console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
})
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
}
缓存目录在cacheDir ="/data/app/el2/100/base/{找到自己的包名}/haps/entry/cache"

原理总结
使用相册拿到的路径,复制一份放在缓存路径下, request.uploadFile(只能读缓存的路径。
通过 uploadTask.on('headerReceive', headerCallback);拿到后端给我们的响应数据code
官网也还提供了request.agent,可查看文档使用
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-file-upload-download#上传应用文件