• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Uploading Files
2
3The **Web** component supports file uploading on a frontend page. You can use [onShowFileSelector()](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9) to process file upload requests sent from a frontend page. If this API is not used, the **Web** component provides default processing for the requests sent from the frontend page.
4
5## Starting File Manager Using onShowFileSelector
6
7In the following example, when a user clicks the **Upload** button on the frontend page, the application receives a file upload request through [onShowFileSelector()](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9), which carries the path of the local file to be uploaded.
8
9
10- Application code:
11
12  ```ts
13  // xxx.ets
14  import { webview } from '@kit.ArkWeb';
15  import { BusinessError } from '@kit.BasicServicesKit';
16  import { picker } from '@kit.CoreFileKit';
17
18  @Entry
19  @Component
20  struct WebComponent {
21    controller: webview.WebviewController = new webview.WebviewController();
22
23    build() {
24      Column() {
25        Web({ src: $rawfile('local.html'), controller: this.controller })
26          .onShowFileSelector((event) => {
27            console.log('MyFileUploader onShowFileSelector invoked');
28            const documentSelectOptions = new picker.DocumentSelectOptions();
29            let uri: string | null = null;
30            const documentViewPicker = new picker.DocumentViewPicker();
31            documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
32              uri = documentSelectResult[0];
33              console.info('documentViewPicker.select to file succeed and uri is:' + uri);
34              if (event) {
35                event.result.handleFileList([uri]);
36              }
37            }).catch((err: BusinessError) => {
38              console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
39            })
40            return true;
41          })
42      }
43    }
44  }
45  ```
46
47
48- Code of the **local.html** page:
49
50  ```html
51  <!DOCTYPE html>
52  <html>
53  <head>
54      <meta charset="utf-8">
55      <title>Document</title>
56  </head>
57
58  <body>
59  <!-- Click the Upload button -->
60  <input type="file" value="file"></br>
61  <meta name="viewport" content="width=device-width" />
62  </body>
63  </html>
64  ```
65![web-app-document](./figures/web-app-document.gif)
66
67## Starting Gallery Using onShowFileSelector
68
69In the following example, when a user clicks the **Upload** button on the frontend page, the application receives a file upload request through [onShowFileSelector()](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9), which carries the path of the local image to be uploaded.
70
71
72- Application code:
73
74  ```ts
75  // xxx.ets
76  import { webview } from '@kit.ArkWeb';
77  import { picker } from '@kit.CoreFileKit';
78  import { photoAccessHelper } from '@kit.MediaLibraryKit';
79
80  @Entry
81  @Component
82  struct WebComponent {
83    controller: webview.WebviewController = new webview.WebviewController()
84
85    async selectFile(result: FileSelectorResult): Promise<void> {
86      let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
87      let photoPicker = new photoAccessHelper.PhotoViewPicker();
88      // Set the MIME file type to IMAGE.
89      photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
90      // Set the maximum number of media files that can be selected.
91      photoSelectOptions.maxSelectNumber = 5;
92      let chooseFile: photoAccessHelper.PhotoSelectResult = await photoPicker.select(photoSelectOptions);
93      // Obtain the list of selected files.
94      result.handleFileList(chooseFile.photoUris);
95    }
96
97    build() {
98      Column() {
99        Web({ src: $rawfile('local.html'), controller: this.controller })
100          .onShowFileSelector((event) => {
101            if (event) {
102              this.selectFile(event.result);
103            }
104            return true;
105          })
106      }
107    }
108  }
109  ```
110
111
112- Code of the **local.html** page:
113
114  ```html
115  <!DOCTYPE html>
116  <html>
117  <head>
118      <meta charset="utf-8">
119      <title>Document</title>
120  </head>
121
122  <body>
123  <!-- Click the Upload button -->
124  <input type="file" value="file"></br>
125  <meta name="viewport" content="width=device-width" />
126  </body>
127  </html>
128  ```
129![web-app-photo](./figures/web-app-photo.gif)
130
131## Starting Camera Using onShowFileSelector
132
133The **Web** component allows the frontend page to call the camera to take photos when uploading image files. You can use the [onShowFileSelector()](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9) API to process the request for uploading image files from the frontend page and start the camera. If no processing is performed, the **Web** component provides the default behavior to process the request for calling the camera.
134
135In the following example, the application listens for the [onShowFileSelector](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9) event and returns **true** to intercept the default ArkWeb dialog box and invoke the system **CameraPicker** to start the camera.
136The application can obtain **AcceptType** to filter target files of different types in a more refined manner.
137
138```ts
139// xxx.ets
140import { webview } from '@kit.ArkWeb';
141import { camera, cameraPicker } from '@kit.CameraKit';
142import { BusinessError } from '@kit.BasicServicesKit';
143import { common } from '@kit.AbilityKit';
144
145async function openCamera(callback: Callback<string>, uiContext: UIContext) {
146  let mContext = uiContext.getHostContext() as common.Context;
147  try {
148    let pickerProfile: cameraPicker.PickerProfile = {
149      cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
150    };
151    let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,
152      [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
153    callback(pickerResult.resultUri);
154  } catch (error) {
155    let err = error as BusinessError;
156    console.error(`the pick call failed. error code: ${err.code}`);
157  }
158}
159
160@Entry
161@Component
162struct Index {
163  webviewController: webview.WebviewController = new webview.WebviewController();
164
165  build() {
166    Column() {
167      Web({ src: $rawfile("webCamera.html"), controller: this.webviewController })
168        .onShowFileSelector((event) => {
169            //You can use event.fileSelector.getAcceptType() and event.fileSelector.isCapture() to determine the file type and filter files to start different file selectors.
170            openCamera((result) => {
171                if (event) {
172                console.log('Title is ' + event.fileSelector.getTitle());
173                console.log('Mode is ' + event.fileSelector.getMode());
174                console.log('Accept types are ' + event.fileSelector.getAcceptType());
175                console.log('Capture is ' + event.fileSelector.isCapture());
176                event.result.handleFileList([result]);
177                }
178            }, this.getUIContext())
179            return true;
180        })
181    }
182    .height('100%')
183    .width('100%')
184  }
185}
186```
187
188HTML page code:
189```html
190<!DOCTYPE html>
191<html lang="en">
192<head>
193    <meta charset="UTF-8">
194    <meta name="viewport" content="width=device-width, initial-scale=1.0">
195    <title>WebCamera</title>
196</head>
197<body>
198    <input type="file" name="photo" id="photo"><br>
199    <img style="display: none;width:200px;" id="img">
200    <script>
201        let photo = document.getElementById("photo");
202        photo.addEventListener("change", preViewImg)
203
204        function preViewImg(event) {
205            let fileReader = new FileReader();
206            let img = document.getElementById("img");
207            fileReader.addEventListener(
208                "load",
209                () => {
210                    // Convert the image file into a Base64 string.
211                    img.src = fileReader.result;
212                },
213                false,
214            );
215            fileReader.readAsDataURL(event.target.files[0]);
216            img.style.display = "block";
217        }
218    </script>
219</body>
220</html>
221```
222![web-app-camera](./figures/web-app-camera.gif)
223
224## Processing File Upload Requests Using the Default ArkWeb Mode
225
226The **accept** attribute is a string that defines the file types that the file **input** component should accept. This string is a comma-separated list of unique file type specifiers. Because a given file type can be specified in many ways, it is important to provide a complete set of type specifiers when you need a file in a given format.
227
228The **capture** attribute is a string used to specify the camera to obtain the data if the **accept** attribute specifies that the input is an image or video. **user** indicates that the front camera and/or microphone should be used. **environment** indicates that the rear camera and/or microphone should be used. If this attribute is absent, the user agent is free to decide what to do. If the preset mode of the request is not available, the user agent may use the default mode.
229
230When the Boolean type attribute **multiple** is specified, the file **input** component allows users to select multiple files.
231
232The sample page includes multiple file selectors, each with different **accept** and **capture** attributes. The impact of these attributes on the camera is as follows:
233
234| accept                      | capture                     | Behavior of the File Selector                                    |
235| --------------------------- | --------------------------- | -------------------------------------------------- |
236| Only the image type             | **environment** or **user**| Starts the camera to take photos.                            |
237| Only the image type              | Unspecified                     | Starts a dialog box. After the user chooses to take a photo, the camera is started to take a photo.      |
238| Only the video type             | **environment** or **user**| Starts the camera to record videos.                            |
239| Only the video type              | Unspecified                     | Starts a dialog box. After the user chooses to take a photo, the camera is started to record videos.      |
240| Image and video types         | **environment** or **user**| Starts the camera to take photos and record videos.                    |
241| Image and video types           | Unspecified                     | Starts a dialog box. After the user chooses to take a photo, the camera is started to take photos and record videos.|
242| Unspecified       | **environment** or **user**| Starts the camera to take photos and record videos.                    |
243| Unspecified         | Unspecified                     | Starts a dialog box. After the user chooses to take a photo, the camera is started to take photos and record videos.|
244| Image and video types are excluded       | **environment** or **user**| Starts the file selection, but not the camera.                   |
245| Image and video types are excluded         | Unspecified                     | Starts the file selection, but not the camera.                  |
246
247> Currently, ArkWeb can identify the following file types:
248>  - Image: tif, xbm, tiff, pjp, jfif, bmp, avif, apng, ico, webp, svg, gif, svgz, jpg, jpeg, png, pjpeg
249>  - Video: mp4, mpg, mpeg, m4v, ogm, ogv, webm
250
251>  **NOTE**
252>
253> By default, ArkWeb starts only the rear camera. The value **user** is not processed as starting the front camera. To start the front camera, use the [onShowFileSelector()](../reference/apis-arkweb/arkts-basic-components-web-events.md#onshowfileselector9) API on the application side.
254
255HTML page code:
256```html
257<!DOCTYPE html>
258<html lang="en">
259<head>
260    <meta charset="UTF-8">
261    <meta name="viewport" content="width=device-width, initial-scale=1.0">
262    <title>WebCamera</title>
263</head>
264<body>
265    <input type="file" name="photo" id="photo" accept="image/*" capture="environment"><br>
266    <input type="file" name="photo2" id="photo2" capture="environment"><br>
267    <input type="file" name="picture" id="picture" accept="image/*"><br>
268    <input type="file" name="none" id="none"><br>
269    <img style="display: none;width:200px" id="img">
270    <script>
271        let photo = document.getElementById("photo");
272        let photo2 = document.getElementById("photo2");
273        let picture = document.getElementById("picture");
274        let none = document.getElementById("none");
275        photo.addEventListener("change", preViewImg)
276        photo2.addEventListener("change", preViewImg)
277        picture.addEventListener("change", preViewImg)
278        none.addEventListener("change", preViewImg)
279
280        function preViewImg(event) {
281            let fileReader = new FileReader();
282            let img = document.getElementById("img");
283            fileReader.addEventListener(
284                "load",
285                () => {
286                    // Convert the image file into a Base64 string.
287                    img.src = fileReader.result;
288                },
289                false,
290            );
291            fileReader.readAsDataURL(event.target.files[0]);
292            img.style.display = "block";
293        }
294    </script>
295</body>
296</html>
297```
298
299Code on the application side:
300```ts
301// xxx.ets
302import { webview } from '@kit.ArkWeb';
303
304@Entry
305@Component
306struct Index {
307  webviewController: webview.WebviewController = new webview.WebviewController()
308
309  build() {
310    Column() {
311      Web({ src: $rawfile("webCamera.html"), controller: this.webviewController })
312    }
313    .height('100%')
314    .width('100%')
315  }
316}
317```
318![web-default-camera](./figures/web-default-camera.gif)
319
320## FAQs
321
322### How to use onShowFileSelector together with the default ArkWeb dialog box?
323
324After a user taps the file upload button, the program preferentially executes the callback in **onShowFileSelector** for logic processing. You can return **false** based on the processing result to start the default ArkWeb dialog box. In this case, you are not advised to start the pickers on the application side at the same time.
325
326### What are the differences between getAcceptType and getMimeTypes in the callback?
327
328**getAcceptType** returns a string array consisting of the file name extensions converted from the **accept** attribute value. **getMimeTypes** returns a string array consisting of the **accept** attribute value that is separated by commas (,).
329
330For example, if the value of **accept** is **video/mp4, .png**, **getAcceptType** returns **.mp4, .m4v; .png**, and **getMimeTypes** returns **video/mp4; .png**.
331
332### What is the default ArkWeb dialog box used for?
333
334When a user selects **Image**, the gallery is started. The user can choose to upload images or videos based on the value of the **accept** attribute. When a user selects **Photo**, the camera is started. The user can choose to take photos or record videos based on the value of the **accept** attribute. When a user selects **File**, the file manager is started. The user can upload any content.
335