1# 应用文件上传下载 2 3应用可以将应用文件上传到网络服务器,也可以从网络服务器下载网络资源文件到本地应用文件目录。 4 5## 上传应用文件 6 7开发者可以使用上传下载模块([ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md))的上传接口将本地文件上传。文件上传过程使用系统服务代理完成,在api12中request.agent.create接口增加了设置代理地址参数,支持用户设置自定义代理地址。 8 9> **说明:** 10> 11> 当前上传应用文件功能,仅支持上传应用缓存文件路径(cacheDir)下的文件。 12> 13> 使用上传下载模块,需[声明权限](../../security/AccessToken/declare-permissions.md):ohos.permission.INTERNET。 14 15以下示例代码演示两种将应用缓存文件路径下的文件上传至网络服务器的方式: 16 17```ts 18// 方式一:request.uploadFile 19// pages/xxx.ets 20import { common } from '@kit.AbilityKit'; 21import fs from '@ohos.file.fs'; 22import { BusinessError, request } from '@kit.BasicServicesKit'; 23 24@Entry 25@Component 26struct Index { 27 build() { 28 Row() { 29 Column() { 30 Button("上传").onClick(() => { 31 // 获取应用文件路径 32 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 33 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 34 let cacheDir = context.cacheDir; 35 36 // 新建一个本地应用文件 37 let file = fs.openSync(cacheDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 38 fs.writeSync(file.fd, 'upload file test'); 39 fs.closeSync(file); 40 41 // 上传任务配置项 42 let files: Array<request.File> = [ 43 //uri前缀internal://cache 对应cacheDir目录 44 { filename: 'test.txt', name: 'test', uri: 'internal://cache/test.txt', type: 'txt' } 45 ] 46 let data: Array<request.RequestData> = [{ name: 'name', value: 'value' }]; 47 let uploadConfig: request.UploadConfig = { 48 url: 'https://xxx', 49 header: { 50 'key1':'value1', 51 'key2':'value2' 52 }, 53 method: 'POST', 54 files: files, 55 data: data 56 } 57 58 // 将本地应用文件上传至网络服务器 59 try { 60 request.uploadFile(context, uploadConfig) 61 .then((uploadTask: request.UploadTask) => { 62 uploadTask.on('complete', (taskStates: Array<request.TaskState>) => { 63 for (let i = 0; i < taskStates.length; i++) { 64 console.info(`upload complete taskState: ${JSON.stringify(taskStates[i])}`); 65 } 66 }); 67 }) 68 .catch((err: BusinessError) => { 69 console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`); 70 }) 71 } catch (error) { 72 let err: BusinessError = error as BusinessError; 73 console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`); 74 } 75 }) 76 } 77 } 78 } 79} 80``` 81 82```ts 83// 方式二:request.agent 84// pages/xxx.ets 85import { common } from '@kit.AbilityKit'; 86import fs from '@ohos.file.fs'; 87import { BusinessError, request } from '@kit.BasicServicesKit'; 88 89@Entry 90@Component 91struct Index { 92 build() { 93 Row() { 94 Column() { 95 Button("上传").onClick(() => { 96 // 获取应用文件路径 97 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 98 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 99 let cacheDir = context.cacheDir; 100 101 // 新建一个本地应用文件 102 let file = fs.openSync(cacheDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 103 fs.writeSync(file.fd, 'upload file test'); 104 fs.closeSync(file); 105 let attachments: Array<request.agent.FormItem> = [{ 106 name: "test", 107 value: [ 108 { 109 filename: "test.txt", 110 path: "./test.txt", 111 }, 112 ] 113 }]; 114 let config: request.agent.Config = { 115 action: request.agent.Action.UPLOAD, 116 url: 'http://xxx', 117 mode: request.agent.Mode.FOREGROUND, 118 overwrite: true, 119 method: "POST", 120 headers: { 121 'key1':'value1', 122 'key2':'value2' 123 }, 124 data: attachments, 125 saveas: "./" 126 }; 127 request.agent.create(context, config).then((task: request.agent.Task) => { 128 task.start((err: BusinessError) => { 129 if (err) { 130 console.error(`Failed to start the upload task, Code: ${err.code} message: ${err.message}`); 131 return; 132 } 133 }); 134 task.on('progress', async(progress) => { 135 console.warn(`/Request upload status ${progress.state}, uploaded ${progress.processed}`); 136 }) 137 task.on('completed', async() => { 138 console.warn(`/Request upload completed`); 139 //该方法需用户管理任务生命周期,任务结束后调用remove释放task对象 140 request.agent.remove(task.tid); 141 }) 142 }).catch((err: BusinessError) => { 143 console.error(`Failed to create a upload task, Code: ${err.code}, message: ${err.message}`); 144 }); 145 }) 146 } 147 } 148 } 149} 150 151``` 152 153## 下载网络资源文件至应用文件目录 154 155开发者可以使用上传下载模块([ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md))的下载接口将网络资源文件下载到应用文件目录。对已下载的网络资源文件,开发者可以使用基础文件IO接口([ohos.file.fs](../../reference/apis-core-file-kit/js-apis-file-fs.md))对其进行访问,使用方式与[应用文件访问](../../file-management/app-file-access.md)一致。文件下载过程使用系统服务代理完成,在api12中request.agent.create接口增加了设置代理地址参数,支持用户设置自定义代理地址。 156 157> **说明:** 158> 159> 当前网络资源文件仅支持下载至应用文件目录。 160> 161> 使用上传下载模块,需[声明权限](../../security/AccessToken/declare-permissions.md):ohos.permission.INTERNET。 162 163以下示例代码演示两种将网络资源文件下载到应用文件目录的方式: 164 165```ts 166// 方式一:request.downloadFile 167// pages/xxx.ets 168// 将网络资源文件下载到应用文件目录并读取一段内容 169import { common } from '@kit.AbilityKit'; 170import fs from '@ohos.file.fs'; 171import { BusinessError, request } from '@kit.BasicServicesKit'; 172import { buffer } from '@kit.ArkTS'; 173 174@Entry 175@Component 176struct Index { 177 build() { 178 Row() { 179 Column() { 180 Button("下载").onClick(() => { 181 // 获取应用文件路径 182 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 183 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 184 let filesDir = context.filesDir; 185 186 try { 187 request.downloadFile(context, { 188 url: 'https://xxxx/xxxx.txt', 189 filePath: filesDir + '/xxxx.txt' 190 }).then((downloadTask: request.DownloadTask) => { 191 downloadTask.on('complete', () => { 192 console.info('download complete'); 193 let file = fs.openSync(filesDir + '/xxxx.txt', fs.OpenMode.READ_WRITE); 194 let arrayBuffer = new ArrayBuffer(1024); 195 let readLen = fs.readSync(file.fd, arrayBuffer); 196 let buf = buffer.from(arrayBuffer, 0, readLen); 197 console.info(`The content of file: ${buf.toString()}`); 198 fs.closeSync(file); 199 }) 200 }).catch((err: BusinessError) => { 201 console.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`); 202 }); 203 } catch (error) { 204 let err: BusinessError = error as BusinessError; 205 console.error(`Invoke downloadFile failed, code is ${err.code}, message is ${err.message}`); 206 } 207 }) 208 } 209 } 210 } 211} 212``` 213```ts 214// 方式二:request.agent 215// pages/xxx.ets 216// 将网络资源文件下载到应用文件目录并读取一段内容 217import { common } from '@kit.AbilityKit'; 218import fs from '@ohos.file.fs'; 219import { BusinessError, request } from '@kit.BasicServicesKit'; 220import { buffer } from '@kit.ArkTS'; 221 222@Entry 223@Component 224struct Index { 225 build() { 226 Row() { 227 Column() { 228 Button("下载").onClick(() => { 229 // 获取应用文件路径 230 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 231 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 232 let filesDir = context.filesDir; 233 234 let config: request.agent.Config = { 235 action: request.agent.Action.DOWNLOAD, 236 url: 'https://xxxx/test.txt', 237 saveas: 'xxxx.txt', 238 gauge: true, 239 overwrite: true, 240 network: request.agent.Network.WIFI, 241 }; 242 request.agent.create(context, config).then((task: request.agent.Task) => { 243 task.start((err: BusinessError) => { 244 if (err) { 245 console.error(`Failed to start the download task, Code: ${err.code} message: ${err.message}`); 246 return; 247 } 248 }); 249 task.on('progress', async (progress) => { 250 console.warn(`/Request download status ${progress.state}, downloaded ${progress.processed}`); 251 }) 252 task.on('completed', async () => { 253 console.warn(`/Request download completed`); 254 let file = fs.openSync(filesDir + '/xxxx.txt', fs.OpenMode.READ_WRITE); 255 let arrayBuffer = new ArrayBuffer(1024); 256 let readLen = fs.readSync(file.fd, arrayBuffer); 257 let buf = buffer.from(arrayBuffer, 0, readLen); 258 console.info(`The content of file: ${buf.toString()}`); 259 fs.closeSync(file); 260 //该方法需用户管理任务生命周期,任务结束后调用remove释放task对象 261 request.agent.remove(task.tid); 262 }) 263 }).catch((err: BusinessError) => { 264 console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`); 265 }); 266 }) 267 } 268 } 269 } 270} 271 272``` 273 274## 添加网络配置 275 276### HTTP拦截 277 278开发者可以通过设置配置文件实现HTTP拦截功能,上传下载模块在应用配置禁用HTTP后,无法创建明文HTTP传输的上传下载任务。配置文件在APP中的路径是:`src/main/resources/base/profile/network_config.json`。请参考网络管理模块[配置文件](../../reference/apis-network-kit/js-apis-net-connection.md#connectionsetapphttpproxy11)配置参数 279 280参考配置文件如下: 281 282```ts 283{ 284 "network-security-config": { 285 "base-config": { 286 "cleartextTrafficPermitted": true, 287 "trust-anchors": [ 288 { 289 "certificates": "/etc/security/certificates" 290 } 291 ] 292 }, 293 "domain-config": [ 294 { 295 "cleartextTrafficPermitted": true, 296 "domains": [ 297 { 298 "include-subdomains": true, 299 "name": "*.example.com" 300 } 301 ], 302 } 303 ] 304 } 305} 306``` 307 308