• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Uploading and Downloading Application Files
2<!--Kit: Basic Services Kit-->
3<!--Subsystem: Request-->
4<!--Owner: @huaxin05-->
5<!--Designer: @hu-kai45-->
6<!--Tester: @murphy1984-->
7<!--Adviser: @zhang_yixin13-->
8
9This topic describes how to upload an application file to a network server and download a network resource file from a network server to a local application file directory.
10
11## Uploading Application Files
12
13You can use **uploadFile()** in [ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md) to upload local files. The system service proxy implements the upload. In API version 12, the parameter for setting the custom proxy address is added to the **request.agent.create** API.
14
15> **NOTE**
16>
17> · Currently, only files in the **cacheDir** directory can be uploaded using **request.uploadFile**; user public files and files in the **cacheDir** directory can be uploaded together using **request.agent**.
18>
19> · The ohos.permission.INTERNET permission is required for using **ohos.request**. For details about how to request the permission, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md).
20>
21> · The **ohos.request** module does not support proxy packet capture tools such as Charles and Fiddler.
22>
23> · Currently, APIs of the **ohos.request** module cannot be called in sub-threads, such as [TaskPool](../../arkts-utils/taskpool-introduction.md).
24
25The following sample code shows how to upload cache files to the server in two ways:
26
27```ts
28// Method 1: Use request.uploadFile.
29// pages/xxx.ets
30import { common } from '@kit.AbilityKit';
31import fs from '@ohos.file.fs';
32import { BusinessError, request } from '@kit.BasicServicesKit';
33
34@Entry
35@Component
36struct Index {
37  build() {
38    Row() {
39      Column() {
40        Button("Upload").onClick(() => {
41          // Obtain the application file path.
42          // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
43          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
44          let cacheDir = context.cacheDir;
45
46          // Create an application file locally.
47          try {
48            let file = fs.openSync(cacheDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
49            fs.writeSync(file.fd, 'upload file test');
50            fs.closeSync(file);
51          } catch (error) {
52            let err: BusinessError = error as BusinessError;
53            console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
54          }
55
56          // Configure the upload task.
57          let files: Array<request.File> = [
58          // "internal://cache" in uri corresponds to the cacheDir directory.
59            { filename: 'test.txt', name: 'test', uri: 'internal://cache/test.txt', type: 'txt' }
60          ]
61          let data: Array<request.RequestData> = [{ name: 'name', value: 'value' }];
62          let uploadConfig: request.UploadConfig = {
63            url: 'https://xxx',
64            header: {
65              'key1':'value1',
66              'key2':'value2'
67            },
68            method: 'POST',
69            files: files,
70            data: data
71          }
72
73          // Upload the created application file to the network server.
74          try {
75            request.uploadFile(context, uploadConfig)
76              .then((uploadTask: request.UploadTask) => {
77                uploadTask.on('complete', (taskStates: Array<request.TaskState>) => {
78                  for (let i = 0; i < taskStates.length; i++) {
79                    console.info(`upload complete taskState: ${JSON.stringify(taskStates[i])}`);
80                  }
81                });
82              })
83              .catch((err: BusinessError) => {
84                console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
85              })
86          } catch (error) {
87            let err: BusinessError = error as BusinessError;
88            console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
89          }
90        })
91      }
92    }
93  }
94}
95```
96
97```ts
98// Method 2: Use request.agent.
99// pages/xxx.ets
100import { common } from '@kit.AbilityKit';
101import fs from '@ohos.file.fs';
102import { BusinessError, request } from '@kit.BasicServicesKit';
103
104@Entry
105@Component
106struct Index {
107  build() {
108    Row() {
109      Column() {
110        Button("Upload").onClick(() => {
111          // Obtain the application file path.
112          // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
113          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
114          let cacheDir = context.cacheDir;
115
116          // Create an application file locally.
117          let file = fs.openSync(cacheDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
118          fs.writeSync(file.fd, 'upload file test');
119          fs.closeSync(file);
120          let attachments: Array<request.agent.FormItem> = [{
121            name: "test",
122            value: [
123              {
124                filename: "test.txt",
125                path: cacheDir + '/test.txt',
126              },
127            ]
128          }];
129          let config: request.agent.Config = {
130            action: request.agent.Action.UPLOAD,
131            url: 'http://xxx',
132            mode: request.agent.Mode.FOREGROUND,
133            overwrite: true,
134            method: "POST",
135            headers: {
136              'key1':'value1',
137              'key2':'value2'
138            },
139            data: attachments
140          };
141          request.agent.create(context, config).then((task: request.agent.Task) => {
142            task.start((err: BusinessError) => {
143              if (err) {
144                console.error(`Failed to start the upload task, Code: ${err.code}  message: ${err.message}`);
145                return;
146              }
147            });
148            task.on('progress', async(progress) => {
149              console.warn(`/Request upload status ${progress.state}, uploaded ${progress.processed}`);
150            })
151            task.on('completed', async() => {
152              console.warn(`/Request upload completed`);
153              // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object.
154              request.agent.remove(task.tid);
155            })
156          }).catch((err: BusinessError) => {
157            console.error(`Failed to create a upload task, Code: ${err.code}, message: ${err.message}`);
158          });
159        })
160      }
161    }
162  }
163}
164
165```
166
167## Downloading Network Resource Files to an Application Directory
168
169You can use **downloadFile()** in [ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md) to download network resource files to a local application directory. You can use the [ohos.file.fs](../../reference/apis-core-file-kit/js-apis-file-fs.md) APIs to access the downloaded files. For details, see [Accessing Application Files](../../file-management/app-file-access.md). The system service agent downloads the files. In API version 12, you can set the address of the agent in **request.agent.create()**.
170
171> **NOTE**
172>
173> Currently, network resource files can be downloaded only to the application file directory.
174>
175> To use **uploadFile()** in **ohos.request**, you need to [declare permissions](../../security/AccessToken/declare-permissions.md): ohos.permission.INTERNET.
176
177The following sample code shows how to download network resource files to the application file directory in two ways:
178
179```ts
180// Method 1: Use request.downloadFile.
181// pages/xxx.ets
182// Download the network resource file to the local application file directory, and read data from the file.
183import { common } from '@kit.AbilityKit';
184import fs from '@ohos.file.fs';
185import { BusinessError, request } from '@kit.BasicServicesKit';
186import { buffer } from '@kit.ArkTS';
187
188@Entry
189@Component
190struct Index {
191  build() {
192    Row() {
193      Column() {
194        Button("Download").onClick(() => {
195          // Obtain the application file path.
196          // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
197          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
198          let filesDir = context.filesDir;
199
200          try {
201            request.downloadFile(context, {
202              url: 'https://xxxx/xxxx.txt',
203              filePath: filesDir + '/xxxx.txt'
204            }).then((downloadTask: request.DownloadTask) => {
205              downloadTask.on('complete', () => {
206                console.info('download complete');
207                let file = fs.openSync(filesDir + '/xxxx.txt', fs.OpenMode.READ_WRITE);
208                let arrayBuffer = new ArrayBuffer(1024);
209                let readLen = fs.readSync(file.fd, arrayBuffer);
210                let buf = buffer.from(arrayBuffer, 0, readLen);
211                console.info(`The content of file: ${buf.toString()}`);
212                fs.closeSync(file);
213              })
214            }).catch((err: BusinessError) => {
215              console.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);
216            });
217          } catch (error) {
218            let err: BusinessError = error as BusinessError;
219            console.error(`Invoke downloadFile failed, code is ${err.code}, message is ${err.message}`);
220          }
221        })
222      }
223    }
224  }
225}
226```
227```ts
228// Method 2: Use request.agent.
229// pages/xxx.ets
230// Download the network resource file to the local application file directory, and read data from the file.
231import { common } from '@kit.AbilityKit';
232import fs from '@ohos.file.fs';
233import { BusinessError, request } from '@kit.BasicServicesKit';
234import { buffer } from '@kit.ArkTS';
235
236@Entry
237@Component
238struct Index {
239  build() {
240    Row() {
241      Column() {
242        Button("Download").onClick(() => {
243          // Obtain the application file path.
244          // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
245          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
246          let filesDir = context.filesDir;
247
248          let config: request.agent.Config = {
249            action: request.agent.Action.DOWNLOAD,
250            url: 'https://xxxx/test.txt',
251            saveas: 'xxxx.txt',
252            gauge: true,
253            overwrite: true,
254            network: request.agent.Network.WIFI,
255          };
256          request.agent.create(context, config).then((task: request.agent.Task) => {
257            task.start((err: BusinessError) => {
258              if (err) {
259                console.error(`Failed to start the download task, Code: ${err.code}  message: ${err.message}`);
260                return;
261              }
262            });
263            task.on('progress', async (progress) => {
264              console.warn(`/Request download status ${progress.state}, downloaded ${progress.processed}`);
265            })
266            task.on('completed', async () => {
267              console.warn(`/Request download completed`);
268              let file = fs.openSync(filesDir + '/xxxx.txt', fs.OpenMode.READ_WRITE);
269              let arrayBuffer = new ArrayBuffer(1024);
270              let readLen = fs.readSync(file.fd, arrayBuffer);
271              let buf = buffer.from(arrayBuffer, 0, readLen);
272              console.info(`The content of file: ${buf.toString()}`);
273              fs.closeSync(file);
274              // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object.
275              request.agent.remove(task.tid);
276            })
277          }).catch((err: BusinessError) => {
278            console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`);
279          });
280        })
281      }
282    }
283  }
284}
285
286```
287
288## Downloading Network Resource Files to the User File
289You can use the [request.agent](../../reference/apis-basic-services-kit/js-apis-request.md#requestagentcreate10) API of [ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md) to download network resource files to the specified user file directory.
290
291> **NOTE**
292>
293> Since API version 20, network resource files can be downloaded to the user file directory.
294
295### Downloading Documents
296
297Call the [save()](../../reference/apis-core-file-kit/js-apis-file-picker.md#save) API of [DocumentViewPicker](../../reference/apis-core-file-kit/js-apis-file-picker.md#documentviewpicker) to save a document and obtain the URI of the user file. Use this URI as the value of the **saveas** field of [Config](../../reference/apis-basic-services-kit/js-apis-request.md#config10) to download the document.
298
299```ts
300import { BusinessError, request } from '@kit.BasicServicesKit';
301import { picker } from '@kit.CoreFileKit';
302import { common } from '@kit.AbilityKit';
303
304@Entry
305@Component
306struct Index {
307  build() {
308    Row() {
309      Column() {
310        Button("Download Document").width("50%").margin({ top: 20 }).height(40).onClick(async () => {
311
312          // Create a documentSaveOptions instance.
313          try {
314            const documentSaveOptions = new picker.DocumentSaveOptions();
315            // (Optional) Name of the file to save. The default value is empty.
316            documentSaveOptions.newFileNames = ["xxxx.txt"];
317            // (Optional) Type of the document to save. The value is in ['Description|File name extensions'] format. To save all files, use 'All files (*.*)|.*'. If there are multiple file name extensions (a maximum of 100 extensions can be filtered), the first one is used by default. If this parameter is not specified, no extension is filtered by default.
318            documentSaveOptions.fileSuffixChoices = ['Document|.txt', '.pdf'];
319            let uri: string = '';
320            // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
321            let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
322            const documentViewPicker = new picker.DocumentViewPicker(context);
323            await documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
324              uri = documentSaveResult[0];
325              console.info('DocumentViewPicker.save to file succeed and uri is:' + uri);
326            }).catch((err: BusinessError) => {
327              console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
328            })
329            if (uri != '') {
330              let config: request.agent.Config = {
331                action: request.agent.Action.DOWNLOAD,
332                url: 'https://xxxx/xxxx.txt',
333                // The saveas field specifies the URI of the file saved by DocumentViewPicker.
334                saveas: uri,
335                gauge: true,
336                // The overwrite field must be set to true.
337                overwrite: true,
338                network: request.agent.Network.WIFI,
339                // The mode field must be set to request.agent.Mode.FOREGROUND.
340                mode: request.agent.Mode.FOREGROUND,
341              };
342              try {
343                request.agent.create(context, config).then((task: request.agent.Task) => {
344                  task.start((err: BusinessError) => {
345                    if (err) {
346                      console.error(`Failed to start the download task, Code: ${err.code}  message: ${err.message}`);
347                      return;
348                    }
349                  });
350                  task.on('progress', async (progress) => {
351                    console.warn(`Request download status ${progress.state}, downloaded ${progress.processed}`);
352                  })
353                  task.on('completed', async (progress) => {
354                    console.warn('Request download completed, ' + JSON.stringify(progress));
355                    // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object.
356                    request.agent.remove(task.tid);
357                  })
358                }).catch((err: BusinessError) => {
359                  console.error(`Failed to operate a download task, Code: ${err.code}, message: ${err.message}`);
360                });
361              } catch (err) {
362                console.error(`Failed to create a download task, err: ${err}`);
363              }
364            }
365          } catch (err) {
366            console.error(`Failed to create a documentSaveOptions, err: ${err}`);
367            return;
368          }
369        })
370      }
371    }
372  }
373}
374```
375
376### Downloading Audios
377
378Call the [save()](../../reference/apis-core-file-kit/js-apis-file-picker.md#save-3) API of [AudioViewPicker](../../reference/apis-core-file-kit/js-apis-file-picker.md#audioviewpicker) to save an audio and obtain the URI of the user file. Use this URI as the value of the **saveas** field of [Config](../../reference/apis-basic-services-kit/js-apis-request.md#config10) to download the audio.
379
380```ts
381import { BusinessError, request } from '@kit.BasicServicesKit';
382import { picker } from '@kit.CoreFileKit';
383import { common } from '@kit.AbilityKit';
384
385@Entry
386@Component
387struct Index {
388  build() {
389    Row() {
390      Column() {
391        Button("Download Audio").width("50%").margin({ top: 20 }).height(40).onClick(async () => {
392          // Create a documentSaveOptions instance.
393          const audioSaveOptions = new picker.AudioSaveOptions();
394          // (Optional) Name of the file to save. The default value is empty.
395          audioSaveOptions.newFileNames = ['xxxx.mp3'];
396
397          let uri: string = '';
398          // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
399          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
400          const audioViewPicker = new picker.AudioViewPicker(context);
401          await audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Array<string>) => {
402            uri = audioSelectResult[0];
403            console.info('AudioViewPicker.save to file succeed and uri is:' + uri);
404          }).catch((err: BusinessError) => {
405            console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
406          })
407          if (uri != '') {
408            let config: request.agent.Config = {
409              action: request.agent.Action.DOWNLOAD,
410              url: 'https://xxxx/xxxx.mp3',
411              // The saveas field specifies the URI of the file saved by AudioViewPicker.
412              saveas: uri,
413              gauge: true,
414              // The overwrite field must be set to true.
415              overwrite: true,
416              network: request.agent.Network.WIFI,
417              // The mode field must be set to request.agent.Mode.FOREGROUND.
418              mode: request.agent.Mode.FOREGROUND,
419            };
420            try {
421              request.agent.create(context, config).then((task: request.agent.Task) => {
422                task.start((err: BusinessError) => {
423                  if (err) {
424                    console.error(`Failed to start the download task, Code: ${err.code}  message: ${err.message}`);
425                    return;
426                  }
427                });
428                task.on('progress', async (progress) => {
429                  console.warn(`Request download status ${progress.state}, downloaded ${progress.processed}`);
430                })
431                task.on('completed', async (progress) => {
432                  console.warn('Request download completed, ' + JSON.stringify(progress));
433                  // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object.
434                  request.agent.remove(task.tid);
435                })
436              }).catch((err: BusinessError) => {
437                console.error(`Failed to operate a download task, Code: ${err.code}, message: ${err.message}`);
438              });
439            } catch (err) {
440              console.error(`Failed to create a download task, err: ${err}`);
441            }
442          }
443        })
444      }
445    }
446  }
447}
448```
449
450### Downloading Images or Videos
451
452Call the [createAsset()](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#createasset-2) API of [PhotoAccessHelper](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper.md) to create a media file and obtain the URI of the user file. Use this URI as the value of the **saveas** field of [Config](../../reference/apis-basic-services-kit/js-apis-request.md#config10) to download the media file.
453
454Permission required: [ohos.permission.WRITE_IMAGEVIDEO](../../security/AccessToken/permissions-for-all-user.md#ohospermissionwrite_media)
455
456[ohos.permission.WRITE_IMAGEVIDEO](../../security/AccessToken/permissions-for-all-user.md#ohospermissionwrite_media) is a [restricted permission](../../security/AccessToken/restricted-permissions.md) of the [system_basic](../../security/AccessToken/app-permission-mgmt-overview.md#basic-concepts-in-the-permission-mechanism) level. If the normal-level application needs to request this permission, its APL level must be declared as system_basic or higher. In addition, you should [request the user_grant permission from users](../../security/AccessToken/request-user-authorization.md).
457
458```ts
459import { BusinessError, request } from '@kit.BasicServicesKit';
460import { photoAccessHelper } from '@kit.MediaLibraryKit';
461
462import { bundleManager } from '@kit.AbilityKit';
463import { abilityAccessCtrl, Context, PermissionRequestResult, common } from '@kit.AbilityKit';
464
465@Entry
466@Component
467struct Index {
468  build() {
469    Row() {
470      Column() {
471        Button("Download Image").width("50%").margin({ top: 20 }).height(40).onClick(async () => {
472          let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
473          bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
474          // Obtain accessTokenID of the application.
475          let tokenID = -1;
476          try {
477            await bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
478              console.info(`/Request getBundleInfoForSelf successfully. Data: ${JSON.stringify(data)}`);
479              tokenID = data.appInfo.accessTokenId;
480            }).catch((err: BusinessError) => {
481              console.error(`GetBundleInfoForSelf failed. Cause: ${err.message}`);
482            });
483          } catch (err) {
484            let message = (err as BusinessError).message;
485            console.error('GetBundleInfoForSelf failed: %{public}s', message);
486          }
487          let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
488
489          let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
490          let grant = true;
491          // Check whether the application has the required permission. This API uses a promise to return the result.
492          await atManager.checkAccessToken(tokenID, 'ohos.permission.WRITE_IMAGEVIDEO')
493            .then((data: abilityAccessCtrl.GrantStatus) => {
494              console.log(`/Request checkAccessToken success, data->${JSON.stringify(data)}`);
495              if (data != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
496                grant = false;
497              }
498            })
499            .catch((err: BusinessError) => {
500              console.error(`CheckAccessToken fail, err->${JSON.stringify(err)}`);
501            });
502
503          if (!grant) {
504            // Display a dialog box for the user to grant the required permission. This API uses an asynchronous callback to return the result.
505            await atManager.requestPermissionsFromUser(context, ['ohos.permission.WRITE_IMAGEVIDEO'])
506              .then((data: PermissionRequestResult) => {
507                console.info('/Request grant:' + JSON.stringify(data));
508                console.info('/Request grant permissions:' + data.permissions);
509                console.info('/Request grant authResults:' + data.authResults);
510                console.info('/Request grant dialogShownResults:' + data.dialogShownResults);
511              }).catch((err: BusinessError) => {
512                console.error('Grant error:' + JSON.stringify(err));
513              });
514          }
515
516          try {
517            let photoType: photoAccessHelper.PhotoType = photoAccessHelper.PhotoType.IMAGE;
518            let extension: string = 'jpg';
519            let options: photoAccessHelper.CreateOptions = {
520              title: 'xxxx'
521            }
522            // Obtain a PhotoAccessHelper instance, which can be used for accessing and modifying media files in an album.
523            let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
524            // Create an image or video asset with the specified file type, file name extension, and options. This API uses a promise to return the result.
525            let uri: string = await phAccessHelper.createAsset(photoType, extension, options);
526            console.info('/Request createAsset uri' + uri);
527            console.info('/Request createAsset successfully');
528
529            let config: request.agent.Config = {
530              action: request.agent.Action.DOWNLOAD,
531              url: 'https://xxxx/xxxx.jpg',
532              // The saveas field specifies the URI of the file saved by PhotoAccessHelper.
533              saveas: uri,
534              gauge: true,
535              // The overwrite field must be set to true.
536              overwrite: true,
537              network: request.agent.Network.WIFI,
538              // The mode field must be set to request.agent.Mode.FOREGROUND.
539              mode: request.agent.Mode.FOREGROUND,
540            };
541            request.agent.create(context, config).then((task: request.agent.Task) => {
542              task.start((err: BusinessError) => {
543                if (err) {
544                  console.error(`Failed to start the download task, Code: ${err.code}  message: ${err.message}`);
545                  return;
546                }
547              });
548              task.on('progress', async (progress) => {
549                console.warn(`Request download status ${progress.state}, downloaded ${progress.processed}`);
550              })
551              task.on('completed', async (progress) => {
552                console.warn('Request download completed, ' + JSON.stringify(progress));
553                // This method requires the user to manage the task lifecycle. After the task is complete, call the remove method to release the task object.
554                request.agent.remove(task.tid);
555              })
556            }).catch((err: BusinessError) => {
557              console.error(`Failed to operate a download task, Code: ${err.code}, message: ${err.message}`);
558            });
559          } catch (err) {
560            console.error(`Failed to create a download task, err: ${err}`);
561          }
562        })
563      }
564    }
565  }
566}
567```
568
569## Configuring Task Speed Limit and Timeout
570
571You can use the APIs of the [ohos.request](../../reference/apis-basic-services-kit/js-apis-request.md) module to upload local files or download network resource files. To set the task speed limit and duration, the [setMaxSpeed](../../reference/apis-basic-services-kit/js-apis-request.md#setmaxspeed18) API is available since API version 18 and the minimum speed and timeout parameters are available in the [request.agent.create](../../reference/apis-basic-services-kit/js-apis-request.md#requestagentcreate10-1) API since API version 20.
572
573The following sample code shows how to configure the speed and timeout of a download task:
574
575```ts
576// pages/xxx.ets
577// Download the network resource file to the local application file directory, and read data from the file.
578import { common } from '@kit.AbilityKit';
579import { fileIo } from '@kit.CoreFileKit';
580import { BusinessError, request } from '@kit.BasicServicesKit';
581import { buffer } from '@kit.ArkTS';
582
583@Entry
584@Component
585struct Index {
586    build() {
587        Row() {
588            Column() {
589                Button("Download").onClick(() => {
590                    // Obtain the application file path.
591                    // Obtain the context from the component and ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext.
592                    let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
593                    let filesDir = context.filesDir;
594
595                    let config: request.agent.Config = {
596                        action: request.agent.Action.DOWNLOAD,
597                        url: 'https://xxxx/test.txt',
598                        saveas: 'xxxx.txt',
599                        gauge: true,
600                        overwrite: true,
601                        network: request.agent.Network.WIFI,
602                        // Rules for setting the minimum speed limit:
603                        // 1. If the task speed is lower than the specified value (for example, 16 × 1024 B/s) for a specified period (for example, 10s), the task fails.
604                        // 2. Conditions for resetting the timer:
605                        //    - The speed at any given second is below the minimum speed limit.
606                        //    - The task is resumed after being paused.
607                        //    - The task is restarted after being stopped.
608                        minSpeed: {
609                            speed: 16 * 1024,
610                            duration: 10
611                        },
612                        // Rules for setting timeout:
613                        // 1. connectionTimeout:
614                        //    - If the time required for establishing a single connection exceeds the specified duration (for example, 60s), the task fails.
615                        //    - The timer is started independently for each connection (not accumulated).
616                        // 2. totalTimeout:
617                        //    - If the total task duration (including connection and transmission time) exceeds the specified duration (for example, 120s), the task fails.
618                        //    - The duration is not counted if the task is paused and is accumulated after the task is resumed.
619                        // 3. Conditions for resetting the timer: The timer is reset when the task fails or stops.
620                        timeout: {
621                            connectionTimeout: 60,
622                            totalTimeout: 120,
623                        }
624                    };
625                    request.agent.create(context, config).then((task: request.agent.Task) => {
626                        task.start((err: BusinessError) => {
627                            if (err) {
628                                console.error(`Failed to start the download task, Code: ${err.code}  message: ${err.message}`);
629                                return;
630                            }
631                            // Set the maximum task speed.
632                            task.setMaxSpeed(10 * 1024 * 1024).then(() => {
633                                console.info(`Succeeded in setting the max speed of the task. result: ${task.tid}`);
634                            }).catch((err: BusinessError) => {
635                                console.error(`Failed to set the max speed of the task. result: ${task.tid}`);
636                            });
637                        });
638                        task.on('progress', async (progress) => {
639                            console.warn(`/Request download status ${progress.state}, downloaded ${progress.processed}`);
640                        })
641                        task.on('completed', async () => {
642                            console.warn(`/Request download completed`);
643                            let file = fileIo.openSync(filesDir + '/xxxx.txt', fileIo.OpenMode.READ_WRITE);
644                            let arrayBuffer = new ArrayBuffer(1024);
645                            let readLen = fileIo.readSync(file.fd, arrayBuffer);
646                            let buf = buffer.from(arrayBuffer, 0, readLen);
647                            console.info(`The content of file: ${buf.toString()}`);
648                            fileIo.closeSync(file);
649                            request.agent.remove(task.tid);
650                        })
651                    }).catch((err: BusinessError) => {
652                        console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`);
653                    });
654                })
655            }
656        }
657    }
658}
659```
660
661## Adding Network Configuration
662
663### Intercepting HTTP
664
665You can set the configuration file to intercept HTTP. After HTTP is disabled for the **ohos.request** module, upload and download tasks using plaintext HTTP cannot be created. The configuration file is stored in the **src/main/resources/base/profile/network_config.json** directory of the application. For details, see the parameters in the [configuration file](../../reference/apis-network-kit/js-apis-net-connection.md#connectionsetapphttpproxy11) of the network management module.
666
667The sample configuration file is as follows:
668
669```ts
670{
671  "network-security-config": {
672    "base-config": {
673      "cleartextTrafficPermitted": true,
674      "trust-anchors": [
675        {
676          "certificates": "/etc/security/certificates"
677        }
678      ]
679    },
680    "domain-config": [
681      {
682        "cleartextTrafficPermitted": true,
683        "domains": [
684          {
685            "include-subdomains": true,
686            "name": "*.example.com"
687          }
688        ],
689      }
690    ]
691  }
692}
693```
694