鸿蒙Next(HarmonyOS) 通过HttpRequest上传文件到服务端(带参数)
·
鸿蒙Next(HarmonyOS) 通过HttpRequest上传文件到服务端(带参数)
1.项目介绍
在移动应用开发中,文件上传是一个常见的需求。今天,我们将一起学习鸿蒙Next如何将本地文件上传到服务器。这个过程虽然设计多个步骤,但只要我们逐步进行,就能够轻松实现。
2.流程概述
首先,我们来展示一下整个文件上传的流程:
| 步骤 | 内容 |
|---|---|
| 1 | 选择文件 |
| 2 | 准备请求,设置请求头和请求体 |
| 3 | 发送请求到服务端 |
| 4 | 处理响应 |
| 5 | 处理文件上传带参的情况 |
2.1 选择本地文件
这里我们写入内容到指定文件下,实际应用只需要替换文件路径即可。
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
import { systemDateTime } from '@kit.BasicServicesKit';
let context = getContext(this) as common.UIAbilityContext
let filesDir = context.filesDir;
let filePath = filesDir + '/test.txt' //文件路径
// 上传文件使用的分隔符
let boundary: string = '----Boundary';
// 写入文件
function writeFile(filePath: string){
// 用文件路径,创建一个文件流。w+: 覆盖式读写,无论该文件存在与否
let fileStream = fileIo.createStreamSync(filePath, "w+");
const content = "这是一段测试文件。 写入时间: " + systemDateTime.getTime().toString();
console.log("文件内容 : ", content);
fileStream.writeSync(content);
fileStream.close();
}
2.2 准备请求,设置请求头和请求体
http post请求的格式是这样的
Content-type:multipart/formdata, boundary=boundary
--boundary
Content-disposition: form-data; name="name"
mike
--boundary
Content-disposition: form-data; name: "pic", filename: "myPic.jpg"
Content-type: image/jpg
<myPic.jpg>
--boundary--
这就是我们上传时需要配置的http
boundary规定的是什么,后面就要一样。boundary 是分割各个参数的分隔符。 注意:boundary结尾时,是–boundary–,代表请求体结束。multipart/formdata 上传的请求头必须包含一个特殊的信息:Content-type 其值也必须是multipart/formdata 如果是一个文件则需要文件信息filename:"myPic.jpg"与文件内容类型Content-type:image/jpg,<myPic.jpg> 则是我们想要上传的图片或者文件。
一定要严格按照规则,否则不会成功
import fs from '@ohos.file.fs';
import { util } from "@kit.ArkTS";
function getBodyData(): string{
let fileName = "";
if (filePath && filePath.includes("/")) {
const fileNameArr = filePath.split("/");
fileName = fileNameArr[fileNameArr.length-1];
}
//选择要上传的文件的内容
let fileContent: string = buf2String(readContentFromFile(filePath))
let bodyStr = "";
bodyStr += "--" + boundary + "\r\n";
bodyStr += "Content-Disposition: form-data; name=\"file\";filename=\"" + fileName + "\"\r\n";
bodyStr += "\r\n";
bodyStr += fileContent;
bodyStr += "\r\n";
bodyStr += "--" + boundary + "--\r\n";
return bodyStr;
}
//从文件读取内容
function readContentFromFile(fileUri: string): ArrayBuffer {
let buf = new ArrayBuffer(1024 * 4);
let file = fs.openSync(fileUri, fs.OpenMode.READ_ONLY);
let readLen = fs.readSync(file.fd, buf, { offset: 0 });
let result = buf.slice(0, readLen)
fs.closeSync(file);
return result
}
//ArrayBuffer转utf8字符串
function buf2String(buf: ArrayBuffer) {
let msgArray = new Uint8Array(buf);
let textDecoder = util.TextDecoder.create("utf-8");
return textDecoder.decodeWithStream(msgArray)
}
2.3 发送请求到服务端
设置Content-Type为multipart/form-data; boundary=xxx, xxx为上传文件使用的分隔符(可自定义)
bodyData为我们的请求额外参数;
import http from '@ohos.net.http';
type RequestListener = (isRequestSuc: boolean, requestData: string) => void;
async function requestPost(url: string, bodyData: string | undefined, httpResponseBlock: RequestListener){
let contentTypeStr = "multipart/form-data; boundary=" + boundary;
let postOptions: http.HttpRequestOptions = {
method: http.RequestMethod.POST,
extraData: bodyData,
header: {
'Content-Type': contentTypeStr
},
connectTimeout: 60000,
};
console.info("requestUrl --- " + url);
const httpRequest = http.createHttp();
httpRequest.request(url, postOptions, (err: Error, data: http.HttpResponse) => {
if (!err) {
console.info('Result:' + data.result);
// console.info('code:' + data.responseCode);
// console.info('type:' + JSON.stringify(data.resultType));
// console.info('header:' + JSON.stringify(data.header));
if (httpResponseBlock) httpResponseBlock(true, data.result as string);
} else {
console.error('error:' + JSON.stringify(err));
if (httpResponseBlock) httpResponseBlock(false, JSON.stringify(err));
}
});
}
2.4 处理响应
文件上传时调用以下代码,处理请求响应。
// 代码调用
writeFile(filePath);
let url = "xxx";
let bodyData = getBodyData();
requestPost(url, bodyData, (isRequestSuc: boolean, requestData: string) => {
if (isRequestSuc) {
console.info('上传成功 --- ' + requestData);
}else {
console.error("请求失败 err --- " + requestData.toString());
}
});
2.5 处理文件上传带参的情况
拼接带参参数时每个参数都需要拼接分隔符格式。
function getBodyData(): string{
let fileName = "";
if (filePath && filePath.includes("/")) {
const fileNameArr = filePath.split("/");
fileName = fileNameArr[fileNameArr.length-1];
}
//选择要上传的文件的内容
let fileContent: string = buf2String(readContentFromFile(filePath))
let bodyStr = "";
// 带参
let verifyDic = new Map<string, string>();
verifyDic.set("param1", "1111");
verifyDic.set("param2", "222");
verifyDic.forEach((value, key) => {
console.info(key + " -- " + value);
bodyStr += "--" + boundary + "\r\n";
bodyStr += "Content-Disposition: form-data; name=\"" + key + "\"\r\n";
bodyStr += "\r\n";
bodyStr += value;
bodyStr += "\r\n";
});
bodyStr += "--" + boundary + "\r\n";
bodyStr += "Content-Disposition: form-data; name=\"file\";filename=\"" + fileName + "\"\r\n";
bodyStr += "\r\n";
bodyStr += fileContent;
bodyStr += "\r\n";
bodyStr += "--" + boundary + "--\r\n";
return bodyStr;
}
⭐️如果对你有用的话,希望可以点点赞,感谢了⭐️
3.完整代码示例
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
import { systemDateTime } from '@kit.BasicServicesKit';
import fs from '@ohos.file.fs';
import { util } from "@kit.ArkTS";
import http from '@ohos.net.http';
let context = getContext(this) as common.UIAbilityContext
let filesDir = context.filesDir;
let filePath = filesDir + '/test.txt' //文件路径
// 上传文件使用的分隔符
let boundary: string = '----Boundary';
// 写入文件
function writeFile(filePath: string){
// 用文件路径,创建一个文件流。w+: 覆盖式读写,无论该文件存在与否
let fileStream = fileIo.createStreamSync(filePath, "w+");
const content = "这是一段测试文件。 写入时间: " + systemDateTime.getTime().toString();
console.log("文件内容 : ", content);
fileStream.writeSync(content);
fileStream.close();
}
function getBodyData(): string{
let fileName = "";
if (filePath && filePath.includes("/")) {
const fileNameArr = filePath.split("/");
fileName = fileNameArr[fileNameArr.length-1];
}
//选择要上传的文件的内容
let fileContent: string = buf2String(readContentFromFile(filePath))
let bodyStr = "";
// 带参
let verifyDic = new Map<string, string>();
verifyDic.set("param1", "1111");
verifyDic.set("param2", "222");
verifyDic.forEach((value, key) => {
console.info(key + " -- " + value);
bodyStr += "--" + boundary + "\r\n";
bodyStr += "Content-Disposition: form-data; name=\"" + key + "\"\r\n";
bodyStr += "\r\n";
bodyStr += value;
bodyStr += "\r\n";
});
bodyStr += "--" + boundary + "\r\n";
bodyStr += "Content-Disposition: form-data; name=\"file\";filename=\"" + fileName + "\"\r\n";
bodyStr += "\r\n";
bodyStr += fileContent;
bodyStr += "\r\n";
bodyStr += "--" + boundary + "--\r\n";
return bodyStr;
}
//从文件读取内容
function readContentFromFile(fileUri: string): ArrayBuffer {
let buf = new ArrayBuffer(1024 * 4);
let file = fs.openSync(fileUri, fs.OpenMode.READ_ONLY);
let readLen = fs.readSync(file.fd, buf, { offset: 0 });
let result = buf.slice(0, readLen)
fs.closeSync(file);
return result
}
//ArrayBuffer转utf8字符串
function buf2String(buf: ArrayBuffer) {
let msgArray = new Uint8Array(buf);
let textDecoder = util.TextDecoder.create("utf-8");
return textDecoder.decodeWithStream(msgArray)
}
type RequestListener = (isRequestSuc: boolean, requestData: string) => void;
async function requestPost(url: string, bodyData: string | undefined, httpResponseBlock: RequestListener){
let contentTypeStr = "multipart/form-data; boundary=" + boundary;
let postOptions: http.HttpRequestOptions = {
method: http.RequestMethod.POST,
extraData: bodyData,
header: {
'Content-Type': contentTypeStr
},
connectTimeout: 60000,
};
console.info("requestUrl --- " + url);
const httpRequest = http.createHttp();
httpRequest.request(url, postOptions, (err: Error, data: http.HttpResponse) => {
if (!err) {
console.info('Result:' + data.result);
// console.info('code:' + data.responseCode);
// console.info('type:' + JSON.stringify(data.resultType));
// console.info('header:' + JSON.stringify(data.header));
if (httpResponseBlock) httpResponseBlock(true, data.result as string);
} else {
console.error('error:' + JSON.stringify(err));
if (httpResponseBlock) httpResponseBlock(false, JSON.stringify(err));
}
});
}
writeFile(filePath);
// 代码调用
let url = "xxx";
let bodyData = getBodyData();
requestPost(url, bodyData, (isRequestSuc: boolean, requestData: string) => {
if (isRequestSuc) {
console.info('上传成功 --- ' + requestData);
}else {
console.error("请求失败 err --- " + requestData.toString());
}
});
⭐️如果对你有用的话,希望可以点点赞,感谢了⭐️
更多推荐



所有评论(0)