uni-app发起请求以及请求封装,上传及下载功能(六)
文章目录
- 一、发起网络请求
- 1.使用及封装
- 2. https 请求配置自签名证书
- 3.拦截器
- 二、上传下载
- 1.上传 uni.uploadFile(OBJECT)
- 2. 下载 uni.downloadFile(OBJECT)
一、发起网络请求
uni-app中内置的uni.request()已经很强大了,简单且好用。为了让其更好用,同时支持拦截器,支持Promise 写法,特对其进行封装。同时支持H5和小程序环境,
uni.request()是一个统一的网络请求接口,支持HTTP和HTTPS协议,可以处理GET、POST等请求方法。这个API提供了基本的HTTP请求功能,可以满足大部分应用的网络通信需求。
由于uni-app是基于Vue.js的,可以使用一些适用于前端的JavaScript网络库如axios 第三方库,支持Promise API,有丰富的拦截器、配置选项和错误处理。
1.使用及封装
使用uni.request()的步骤如下:
- 在需要发起网络请求的页面中引入uni.request()方法。
- 调用uni.request()方法,并传入相应的参数,包括请求地址、请求方法、请求头部和请求数据等。
- 监听请求的成功和失败回调,并在回调函数中处理返回的数据。
参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | 开发者服务器接口地址 | ||
data | Object/String/ArrayBuffer | 否 | 请求的参数 | App 3.3.7 以下不支持 ArrayBuffer 类型 | |
header | Object | 否 | 设置请求的 header,header 中不能设置 Referer | App、H5端会自动带上cookie,且H5端不可手动修改 | |
method | String | 否 | GET | 有效值详见下方说明 | |
timeout | Number | 否 | 60000 | 超时时间,单位 ms | H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 |
dataType | String | 否 | json | 如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse | |
responseType | String | 否 | text | 设置响应的数据类型。合法值:text、arraybuffer | 支付宝小程序不支持 |
sslVerify | Boolean | 否 | true | 验证 ssl 证书 | 仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包 |
defer | Boolean | 否 | false | 控制当前请求是否延时至首屏内容渲染后发送 | 百度小程序 3.310.11+ |
success | Function | 否 | 收到开发者服务器成功返回的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
- method 有效值:method有效值必须大写,每个平台支持的method有效值不同
- success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
data | Object/String/ArrayBuffer | 开发者服务器返回的数据 |
statusCode | Number | 开发者服务器返回的 HTTP 状态码 |
header | Object | 开发者服务器返回的 HTTP Response Header |
cookies | Array<string> | 开发者服务器返回的 cookies,格式为字符串数组 |
-
data 数据说明
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:- 对于 GET 方法,会将数据转换为 query string。例如 { name: ‘name’, age: 18 } 转换后的结果是 name=name&age=18。
- 对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会进行 JSON 序列化。
- 对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换为 query string。
/** * 请求组件封装 * url 请求地址 * data 请求参数 * method 请求的方法 默认get请求 * contentType 请求内容类型 1 json 强求 2 form表单请求 */ function request({url, data, method='GET', contentType = '1'}) { let header = { 'content-type': contentType == 1 ? 'application/json' : 'application/x-www-form-urlencoded' } let baseUrl = 'http://192.168.0.78'; console.log(baseUrl + url) return new Promise((resolve, reject) => { uni.request({ url: baseUrl + url, data, method, header, success: (res) => { console.log(res) if (res.statusCode == 200) { resolve(res.data) } else if (res.statusCode == 401) { uni.showToast({ icon: 'none', title: '未登录或登录状态已超时', duration:1500, }) } else if (res.statusCode == 405) { uni.showToast({ icon: 'none', title: '请求方法错误', duration:1500, }) } else { uni.showToast({ icon: 'none', title: '请求错误' + res.statusCode, duration:1500, }) } }, }) }) }
-
返回值
如果希望返回一个 requestTask 对象,需要至少传入 success / fail / complete 参数中的一个var requestTask = uni.request({ url: 'http://192.168.0.18:8080/request', //仅为示例,并非真实接口地址。 complete: ()=> {} }); requestTask.abort();
如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象
通过 requestTask,可中断请求任务。
requestTask 对象的方法列表方法 参数 说明 abort 中断请求任务 offHeadersReceived 取消监听 HTTP Response Header 事件,仅微信小程序平台支持 onHeadersReceived 监听 HTTP Response Header 事件。会比请求完成事件更早,仅微信小程序平台支持 const requestTask = uni.request({ url: 'http://192.168.0.18:8080/request', //仅为示例,并非真实接口地址。 data: { name: 'name', age: 18 }, success: function(res) { console.log(res.data); } }); // 中断请求任务 requestTask.abort()
2. https 请求配置自签名证书
uni.configMTLS(OBJECT)
https 请求配置自签名证书,只有app支持,其他都不支持
- OBJECT 参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
certificates | Array<certificate> | 是 | certificates 为数组,支持为多个域名配置自签名证书 |
success | Function(callbackObject) | 否 | 接口调用成功的回调函数 |
fail | Function(callbackObject) | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
- certificate 参数说明 证书配置项
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
host | string | 是 | 对应请求的域名(注意:不要协议部分) |
client | string | 否 | 客户端证书(服务器端需要验证客户端证书时需要配置此项,格式要求请参考下面的证书格式说明,注意 iOS 平台客户端证书只支持 .p12 类型的证书。HarmonyOS Next 上是证书路径) |
keyPath | string | 否 | 证书秘钥的路径,只支持 HarmonyOS Next (HBuilderX 4.31) |
clientPassword | string | 否 | 客户端证书对应的密码(客户端证书存在时必须配置此项。HarmonyOS Next 上是证书秘钥的密码) |
server | Array<string> | 否 | 服务器端证书(客户端需要对服务器端证书做校验时需要配置此项,通常使用自签名证书时才需要配置,格式要求请参考下面的证书格式说明,注意 iOS 平台服务器端证书只支持 .cer 类型的证书,不仅仅验证公钥,还要验证整个证书链,请保证证书的完整性。HarmonyOS Next 不支持) |
- 证书格式说明
证书支持两种格式,文件格式和 Base64字符串格式- 文件格式说明:可将证书文件放到工程的 ‘static’ 目录中(当然也可以通过请求下载到本地),然后填写文件路径,
- Base64String格式说明:将证书文件的二进制转换为 Base64String 字符串,然后在字符串前面添加’data:cert/pem;base64,'前缀,示例:‘data:cert/pem;base64,xxx’ xxx 代表真实的证书 base64String
uni.configMTLS({
certificates: [{
'host': 'www.baidu.com',
'client': '/static/client.p12',
'clientPassword': '123456789',
'server': ['/static/server.cer'],
}],
success ({code}) {
// 类型是Number 成功返回 0,失败返回相应 code 码
}
});
3.拦截器
uni.addInterceptor(STRING, OBJECT)
-
STRING 参数说明
需要拦截的api名称,如:uni.addInterceptor(‘request’, OBJECT) ,将拦截 uni.request()注
仅支持异步接口,如:uni.setStorage(OBJECT),暂不支持同步接口如:uni.setStorageSync(KEY,DATA)
uniCloud请求云端接口时(callFunction、uploadFile等)也会使用uni.request发送请求,请确保拦截器内不错误的处理此类请求 -
OBJECT 参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
invoke | Function | 否 | 拦截前触发 | ||
returnValue | Function | 否 | 方法调用后触发,处理返回值 | ||
success | Function | 否 | 成功回调拦截 | ||
fail | Function | 否 | 失败回调拦截 | ||
complete | Function | 否 | 完成回调拦截 |
uni.addInterceptor('request', {
invoke(args) {
// 在请求发送之前的处理
console.log('请求拦截:', args);
// 可以修改args中的参数
// 例如: 添加token
// args.header = args.header || {};
// args.header['Authorization'] = 'Bearer ' + getToken();
},
success(args) {
// 在请求成功之后的处理
console.log('请求成功拦截:', args);
},
fail(err) {
// 在请求失败之后的处理
console.error('请求失败拦截:', err);
},
complete() {
// 在请求结束之后的处理
console.log('请求结束拦截');
}
});
uni.addInterceptor({
returnValue(args) {
// 只返回 data 字段
return args.data
}
})
- 删除拦截器
uni.removeInterceptor(STRING)
STRING:需要删除拦截器的api名称
// 移除请求拦截器
uni.removeInterceptor('request');
二、上传下载
1.上传 uni.uploadFile(OBJECT)
将本地资源上传到开发者服务器,客户端发起一个 POST 请求,其中 content-type 为 multipart/form-data。 如页面通过 uni.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。
注:
1:在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。
2::App支持多文件上传,微信小程序只支持单文件上传,传多个文件需要反复调用本API。所以跨端的写法就是循环调用本API。
3:网络请求的 超时时间 可以统一在 manifest.json 中配置 networkTimeout。
4:支付宝小程序开发工具上传文件返回的http状态码为字符串形式,支付宝小程序真机返回的状态码为数字形式
-
OBJECT参数说明
参数名 类型 必填 说明 平台差异说明 url String 是 开发者服务器 url files Array 是(files和filePath选其一) 需要上传的文件列表。使用 files 时,filePath 和 name 不生效。 App、H5( 2.6.15+) fileType String 是 开发者服务器 url 仅支付宝小程序,且必填。 file File 否 要上传的文件对象。 仅H5(2.6.15+)支持 filePath String 是(files和filePath选其一) 要上传文件资源的路径。 name String 是 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 header Object 否 HTTP 请求 Header, header 中不能设置 Referer。 timeout String 否 超时时间,单位 ms H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序、支付宝小程序、抖音小程序、快手小程序 formData Object 否 HTTP 请求中其他额外的 form data success String 否 接口调用成功的回调函数 fail String 否 接口调用失败的回调函数 complete String 否 接口调用结束的回调函数(调用成功、失败都会执行) // html <button @click="handleUpload">上传文件</button> // js uni.chooseImage({ success: (chooseImageRes) => { console.log(chooseImageRes) const tempFilePaths = chooseImageRes.tempFilePaths; uni.uploadFile({ url: 'http://192.168.0.18:8080/jeecg-boot/sys/common/uploadImagea', //仅为示例,非真实的接口地址 filePath: tempFilePaths[0], name: 'file', formData: { 'user': 'test' }, success: (uploadFileRes) => { console.log(uploadFileRes.data); } }); } });
-
返回值
如果希望返回一个 uploadTask 对象,需要至少传入 success / fail / complete 参数中的一个var uploadTask = uni.uploadFile({ url: 'http://192.168.0.18:8080/jeecg-boot/sys/common/uploadImagea', //仅为示例,并非真实接口地址。 complete: ()=> {} }); uploadTask.abort();
如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象
通过uploadTask ,可以监听上传进度变化事件,以及取消上传任务
uploadTask 对象的方法列表方法 参数 说明 abort 中断上传任务 onProgressUpdate callback 监听上传进度变化 onHeadersReceived callback 监听 HTTP Response Header 事件。会比请求完成事件更早,仅微信小程序平台支持 offProgressUpdate callback 取消监听上传进度变化事件,仅微信小程序平台支持 offHeadersReceived callback 取消监听 HTTP Response Header 事件,仅微信小程序平台支持 let uploadTask = uni.uploadFile({ url: 'http://192.168.0.18:8084/jeecg-boot/sys/common/uploadImagea', //仅为示例,非真实的接口地址 complete: ()=> {} }); console.log(uploadTask) uploadTask.onProgressUpdate((res) => { console.log(res) console.log('上传进度' + res.progress); console.log('已经上传的数据长度' + res.totalBytesSent); console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend); // 测试条件,取消上传任务。 if (res.progress > 50) { uploadTask.abort(); } });
注:后面会有文章对uni.chooseImage的介绍
2. 下载 uni.downloadFile(OBJECT)
下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径。
注:
在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。
在h5上是跨域的,用户需要处理好跨域问题。
网络请求的 超时时间 可以统一在 manifest.json 中配置 networkTimeout。
- OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
url | String | 是 | 下载资源的 url | |
header | Object | 否 | HTTP 请求 Header, header 中不能设置 Referer。 | |
timeout | String | 否 | 超时时间,单位 ms | H5、APP、微信小程序、支付宝小程序、抖音小程序、快手小程序 |
filePath | String | 否 | 指定文件下载后存储的路径 (本地路径) | 小程序端支持(微信IOS小程序保存到相册需要添加此字段才可以正常保存) |
success | String | 否 | 下载成功后以 tempFilePath 的形式传给页面,res = {tempFilePath: ‘文件的临时路径’} | |
fail | String | 否 | 接口调用失败的回调函数 | |
complete | String | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
注: 文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用 uni.saveFile,才能在应用下次启动时访问得到。
- success 返回参数说明
参数 | 类型 | 说明 | 平台差异说明 |
---|---|---|---|
tempFilePath | String | 临时文件路径,下载后的文件会存储到一个临时文件 | 微信小程序、支付宝小程序、百度小程序、抖音小程序、飞书小程序 |
statusCode | Number | 开发者服务器返回的 HTTP 状态码 | 微信小程序、QQ小程序、百度小程序、抖音小程序、飞书小程序 |
apFilePath | String | 下载文件保存的路径(本地临时文件)。入参未指定 filePath 的情况下可用 | 支付宝小程序 |
filePath | String | 用户文件路径 (本地路径)。传入 filePath 时会返回,跟传入的 filePath 一致 | 微信小程序、支付宝小程序、抖音小程序、飞书小程序 |
fileContent | Buffer | 文件内容 | QQ小程序 |
uni.downloadFile({
url: 'http://192.168.0.18:8084/jeecg-boot/sys/common/file/test', //仅为示例,并非真实的资源
success: (res) => {
if (res.statusCode === 200) {
console.log('下载成功');
}
}
});
-
返回值
如果希望返回一个 downloadTask 对象,需要至少传入 success / fail / complete 参数中的一个。var downloadTask = uni.downloadFile({ url: 'https://www.example.com/file/test', //仅为示例,并非真实接口地址。 complete: ()=> {} }); downloadTask.abort();
如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象
通过 downloadTask,可监听下载进度变化事件,以及取消下载任务。 -
downloadTask 对象的方法列表
方法 参数 说明 abort 中断下载任务 onProgressUpdate callback 监听下载进度变化 onHeadersReceived callback 监听 HTTP Response Header 事件,会比请求完成事件更早,仅微信小程序平台支持 offProgressUpdate callback 取消监听下载进度变化事件,仅微信小程序平台支持 offHeadersReceived callback 取消监听 HTTP Response Header 事件,仅微信小程序平台支持 const downloadTask = uni.downloadFile({ url: 'http://192.168.0.18:8084/jeecg-boot/sys/common/download', //仅为示例,并非真实的资源 success: (res) => { if (res.statusCode === 200) { console.log('下载成功'); } } }); downloadTask.onProgressUpdate((res) => { console.log('下载进度' + res.progress); console.log('已经下载的数据长度' + res.totalBytesWritten); console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite); // 满足测试条件,取消下载任务。 if (res.progress > 50) { downloadTask.abort(); } });