1# Invoking Application Functions on the Frontend Page
2
3
4You can use the **Web** component to register application code with frontend pages. After the registration is done, frontend pages can use the registered object names to call application functions.
5
6Two methods are available for registering the application code:<br>
7
8- Call [javaScriptProxy()](../reference/apis-arkweb/ts-basic-components-web.md#javascriptproxy) during **Web** component initialization.
9- Call [registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy) after **Web** component initialization. This API must be used together with [deleteJavaScriptRegister](../reference/apis-arkweb/js-apis-webview.md#deletejavascriptregister) to prevent memory leak.
10
11
12The following example registers the **test()** function with the frontend page. This way, the **test()** function can be triggered and run on the frontend page.
13
14
15- Sample code for using [javaScriptProxy()](../reference/apis-arkweb/ts-basic-components-web.md#javascriptproxy):
16
17  ```ts
18  // xxx.ets
19  import { webview } from '@kit.ArkWeb';
20  import { BusinessError } from '@kit.BasicServicesKit';
21
22  class testClass {
23    constructor() {
24    }
25
26    test(): string {
27      return 'ArkTS Hello World!';
28    }
29  }
30
31  @Entry
32  @Component
33  struct WebComponent {
34    webviewController: webview.WebviewController = new webview.WebviewController();
35    // Declare the object to be registered.
36    @State testObj: testClass = new testClass();
37
38    build() {
39      Column() {
40        Button('deleteJavaScriptRegister')
41          .onClick(() => {
42            try {
43              this.webviewController.deleteJavaScriptRegister("testObjName");
44            } catch (error) {
45              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
46            }
47          })
48        // Load the local index.html page.
49        Web({ src: $rawfile('index.html'), controller: this.webviewController})
50          // Inject the object to the web client.
51          .javaScriptProxy({
52            object: this.testObj,
53            name: "testObjName",
54            methodList: ["test"],
55            controller: this.webviewController,
56            // Optional parameter.
57            asyncMethodList: [],
58            permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
59                        '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
60                        '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
61                        '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
62                        '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
63          })
64      }
65    }
66  }
67  ```
68
69
70- Sample code for using [registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy):
71
72  ```ts
73  // xxx.ets
74  import { webview } from '@kit.ArkWeb';
75  import { BusinessError } from '@kit.BasicServicesKit';
76
77  class testClass {
78    constructor() {
79    }
80
81    test(): string {
82      return "ArkUI Web Component";
83    }
84
85    toString(): void {
86      console.log('Web Component toString');
87    }
88  }
89
90  @Entry
91  @Component
92  struct Index {
93    webviewController: webview.WebviewController = new webview.WebviewController();
94    @State testObj: testClass = new testClass();
95
96    build() {
97      Column() {
98        Button('refresh')
99          .onClick(() => {
100            try {
101              this.webviewController.refresh();
102            } catch (error) {
103              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
104            }
105          })
106        Button('Register JavaScript To Window')
107          .onClick(() => {
108            try {
109              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"],
110                      // Optional parameter: asyncMethodList
111                      [],
112                      // Optional parameter: permission
113                      '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' +
114                      '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' +
115                      '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' +
116                      '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' +
117                      '{"scheme":"u","host":"v","port":"","path":""}]}]}}'
118              );
119            } catch (error) {
120              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
121            }
122          })
123        Button('deleteJavaScriptRegister')
124          .onClick(() => {
125            try {
126              this.webviewController.deleteJavaScriptRegister("testObjName");
127            } catch (error) {
128              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
129            }
130          })
131        Web({ src: $rawfile('index.html'), controller: this.webviewController })
132      }
133    }
134  }
135  ```
136
137  > **NOTE**
138  >
139  > - If you use [registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy) to register a function, call [refresh()](../reference/apis-arkweb/js-apis-webview.md#refresh) for the function to take effect.
140
141- The optional parameter permission is a JSON string. The following is an example:
142  ```json
143  {
144    "javascriptProxyPermission": {
145      "urlPermissionList": [       // Object-level permission. If it is granted, all methods are available.
146        {
147          "scheme": "resource",    // Exact match. The value cannot be empty.
148          "host": "rawfile",       // Exact match. The value cannot be empty.
149          "port": "",              // Exact match. If the value is empty, it is not checked.
150          "path": ""               // Prefix match. If the value is empty, it is not checked.
151        },
152        {
153          "scheme": "https",       // Exact match. The value cannot be empty.
154          "host": "xxx.com",       // Exact match. The value cannot be empty.
155          "port": "",                  // Exact match. If the value is empty, it is not checked.
156          "path": "a/b/c"          // Prefix match. If the value is empty, it is not checked.
157        }
158      ],
159      "methodList": [
160        {
161          "methodName": "test",
162          "urlPermissionList": [   // Method-level permission.
163            {
164              "scheme": "https",   // Exact match. The value cannot be empty.
165              "host": "xxx.com",   // Exact match. The value cannot be empty.
166              "port": "",          // Exact match. If the value is empty, it is not checked.
167              "path": ""           // Prefix match. If the value is empty, it is not checked.
168            },
169            {
170              "scheme": "resource",    // Exact match. The value cannot be empty.
171              "host": "rawfile",   // Exact match. The value cannot be empty.
172              "port": "",          // Exact match. If the value is empty, it is not checked.
173              "path": ""           // Prefix match. If the value is empty, it is not checked.
174            }
175          ]
176        },
177        {
178          "methodName": "test11",
179          "urlPermissionList": [   // Method-level permission.
180            {
181              "scheme": "q",       // Exact match. The value cannot be empty.
182              "host": "r",         // Exact match. The value cannot be empty.
183              "port": "",          // Exact match. If the value is empty, it is not checked.
184              "path": "t"          // Prefix match. If the value is empty, it is not checked.
185            },
186            {
187              "scheme": "u",       // Exact match. The value cannot be empty.
188              "host": "v",         // Exact match. The value cannot be empty.
189              "port": "",          // Exact match. If the value is empty, it is not checked.
190              "path": ""           // Prefix match. If the value is empty, it is not checked.
191            }
192          ]
193        }
194      ]
195    }
196  }
197  ```
198
199- Sample code for invoking application functions on the **index.html** frontend page:
200
201  ```html
202  <!-- index.html -->
203  <!DOCTYPE html>
204  <html>
205  <body>
206  <button type="button" onclick="callArkTS()">Click Me!</button>
207  <p id="demo"></p>
208  <script>
209      function callArkTS() {
210          let str = testObjName.test();
211          document.getElementById("demo").innerHTML = str;
212          console.info('ArkTS Hello World! :' + str);
213      }
214  </script>
215  </body>
216  </html>
217  ```
218## Usage of Complex Types
219- Sample code for passing arrays between the application side and the frontend page:
220  ```ts
221  // xxx.ets
222  import { webview } from '@kit.ArkWeb';
223  import { BusinessError } from '@kit.BasicServicesKit';
224
225  class testClass {
226    constructor() {
227    }
228
229    test(): Array<Number> {
230      return [1, 2, 3, 4]
231    }
232
233    toString(param: String): void {
234      console.log('Web Component toString' + param);
235    }
236  }
237
238  @Entry
239  @Component
240  struct Index {
241    webviewController: webview.WebviewController = new webview.WebviewController();
242    @State testObj: testClass = new testClass();
243
244    build() {
245      Column() {
246        Button('refresh')
247          .onClick(() => {
248            try {
249              this.webviewController.refresh();
250            } catch (error) {
251              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
252            }
253          })
254        Button('Register JavaScript To Window')
255          .onClick(() => {
256            try {
257              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
258            } catch (error) {
259              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
260            }
261          })
262        Button('deleteJavaScriptRegister')
263          .onClick(() => {
264            try {
265              this.webviewController.deleteJavaScriptRegister("testObjName");
266            } catch (error) {
267              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
268            }
269          })
270        Web({ src: $rawfile('index.html'), controller: this.webviewController })
271      }
272    }
273  }
274  ```
275
276  ```html
277  <!-- index.html -->
278  <!DOCTYPE html>
279  <html>
280  <body>
281  <button type="button" onclick="callArkTS()">Click Me!</button>
282  <p id="demo"></p>
283  <script>
284      function callArkTS() {
285          testObjName.toString(testObjName.test());
286      }
287  </script>
288  </body>
289  </html>
290  ```
291- Sample code for passing data of primitive types (not of Function or any other complex type) between the application side and the frontend page:
292  ```ts
293  // xxx.ets
294  import { webview } from '@kit.ArkWeb';
295  import { BusinessError } from '@kit.BasicServicesKit';
296
297  class student {
298    name: string = '';
299    age: string = '';
300  }
301
302  class testClass {
303    constructor() {
304    }
305
306    // Data of primitive types to pass: name:"jeck", age:"12"
307    test(): student {
308      let st: student = { name: "jeck", age: "12" };
309      return st;
310    }
311
312    toString(param: ESObject): void {
313      console.log('Web Component toString' + param["name"]);
314    }
315  }
316
317  @Entry
318  @Component
319  struct Index {
320    webviewController: webview.WebviewController = new webview.WebviewController();
321    @State testObj: testClass = new testClass();
322
323    build() {
324      Column() {
325        Button('refresh')
326          .onClick(() => {
327            try {
328              this.webviewController.refresh();
329            } catch (error) {
330              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
331            }
332          })
333        Button('Register JavaScript To Window')
334          .onClick(() => {
335            try {
336              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
337            } catch (error) {
338              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
339            }
340          })
341        Button('deleteJavaScriptRegister')
342          .onClick(() => {
343            try {
344              this.webviewController.deleteJavaScriptRegister("testObjName");
345            } catch (error) {
346              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
347            }
348          })
349        Web({ src: $rawfile('index.html'), controller: this.webviewController })
350      }
351    }
352  }
353  ```
354
355  ```html
356  <!-- index.html -->
357  <!DOCTYPE html>
358  <html>
359  <body>
360  <button type="button" onclick="callArkTS()">Click Me!</button>
361  <p id="demo"></p>
362  <script>
363      function callArkTS() {
364          testObjName.toString(testObjName.test());
365      }
366  </script>
367  </body>
368  </html>
369  ```
370
371- Sample code for invoking a callback of the frontend page from the application side:
372  ```ts
373  // xxx.ets
374  import { webview } from '@kit.ArkWeb';
375  import { BusinessError } from '@kit.BasicServicesKit';
376
377  class testClass {
378    constructor() {
379    }
380
381    test(param: Function): void {
382      param("call callback");
383    }
384
385    toString(param: String): void {
386      console.log('Web Component toString' + param);
387    }
388  }
389
390  @Entry
391  @Component
392  struct Index {
393    webviewController: webview.WebviewController = new webview.WebviewController();
394    @State testObj: testClass = new testClass();
395
396    build() {
397      Column() {
398        Button('refresh')
399          .onClick(() => {
400            try {
401              this.webviewController.refresh();
402            } catch (error) {
403              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
404            }
405          })
406        Button('Register JavaScript To Window')
407          .onClick(() => {
408            try {
409              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
410            } catch (error) {
411              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
412            }
413          })
414        Button('deleteJavaScriptRegister')
415          .onClick(() => {
416            try {
417              this.webviewController.deleteJavaScriptRegister("testObjName");
418            } catch (error) {
419              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
420            }
421          })
422        Web({ src: $rawfile('index.html'), controller: this.webviewController })
423      }
424    }
425  }
426  ```
427
428  ```html
429  <!-- index.html -->
430  <!DOCTYPE html>
431  <html>
432  <body>
433  <button type="button" onclick="callArkTS()">Click Me!</button>
434  <p id="demo"></p>
435  <script>
436      function callArkTS() {
437          testObjName.test(function(param){testObjName.toString(param)});
438      }
439  </script>
440  </body>
441  </html>
442  ```
443
444- Sample code for calling the function in an object of the frontend page from the application side:
445  ```ts
446  // xxx.ets
447  import { webview } from '@kit.ArkWeb';
448  import { BusinessError } from '@kit.BasicServicesKit';
449
450  class testClass {
451    constructor() {
452    }
453
454    test(param: ESObject): void {
455      param.hello("call obj func");
456    }
457
458    toString(param: String): void {
459      console.log('Web Component toString' + param);
460    }
461  }
462
463  @Entry
464  @Component
465  struct Index {
466    webviewController: webview.WebviewController = new webview.WebviewController();
467    @State testObj: testClass = new testClass();
468
469    build() {
470      Column() {
471        Button('refresh')
472          .onClick(() => {
473            try {
474              this.webviewController.refresh();
475            } catch (error) {
476              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
477            }
478          })
479        Button('Register JavaScript To Window')
480          .onClick(() => {
481            try {
482              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
483            } catch (error) {
484              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
485            }
486          })
487        Button('deleteJavaScriptRegister')
488          .onClick(() => {
489            try {
490              this.webviewController.deleteJavaScriptRegister("testObjName");
491            } catch (error) {
492              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
493            }
494          })
495        Web({ src: $rawfile('index.html'), controller: this.webviewController })
496      }
497    }
498  }
499  ```
500
501  ```html
502  <!-- index.html -->
503  <!DOCTYPE html>
504  <html>
505  <body>
506  <button type="button" onclick="callArkTS()">Click Me!</button>
507  <p id="demo"></p>
508  <script>
509      // Method 1
510      class Student {
511          constructor(nameList) {
512              this.methodNameListForJsProxy = nameList;
513          }
514
515          hello(param) {
516              testObjName.toString(param)
517          }
518      }
519      var st = new Student(["hello"])
520
521      // Method 2
522      // Create a constructor, with the first letter of the constructor capitalized.
523      function Obj1(){
524          this.methodNameListForJsProxy=["hello"];
525          this.hello=function(param){
526              testObjName.toString(param)
527          };
528      }
529      // Use the constructor to create an object using the new keyword.
530      var st1 = new Obj1();
531
532      function callArkTS() {
533          testObjName.test(st);
534          testObjName.test(st1);
535      }
536  </script>
537  </body>
538  </html>
539  ```
540
541- Sample code for calling the function in an object of the application side from the frontend page:
542  ```ts
543  // xxx.ets
544  import { webview } from '@kit.ArkWeb';
545  import { BusinessError } from '@kit.BasicServicesKit';
546
547  class ObjOther {
548    methodNameListForJsProxy: string[]
549
550    constructor(list: string[]) {
551      this.methodNameListForJsProxy = list
552    }
553
554    testOther(json: string): void {
555      console.info(json)
556    }
557  }
558
559  class testClass {
560    ObjReturn: ObjOther
561
562    constructor() {
563      this.ObjReturn = new ObjOther(["testOther"]);
564    }
565
566    test(): ESObject {
567      return this.ObjReturn
568    }
569
570    toString(param: string): void {
571      console.log('Web Component toString' + param);
572    }
573  }
574
575  @Entry
576  @Component
577  struct Index {
578    webviewController: webview.WebviewController = new webview.WebviewController();
579    @State testObj: testClass = new testClass();
580
581    build() {
582      Column() {
583        Button('refresh')
584          .onClick(() => {
585            try {
586              this.webviewController.refresh();
587            } catch (error) {
588              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
589            }
590          })
591        Button('Register JavaScript To Window')
592          .onClick(() => {
593            try {
594              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
595            } catch (error) {
596              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
597            }
598          })
599        Button('deleteJavaScriptRegister')
600          .onClick(() => {
601            try {
602              this.webviewController.deleteJavaScriptRegister("testObjName");
603            } catch (error) {
604              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
605            }
606          })
607        Web({ src: $rawfile('index.html'), controller: this.webviewController })
608      }
609    }
610  }
611  ```
612
613  ```html
614  <!-- index.html -->
615  <!DOCTYPE html>
616  <html>
617  <body>
618  <button type="button" onclick="callArkTS()">Click Me!</button>
619  <p id="demo"></p>
620  <script>
621      function callArkTS() {
622        testObjName.test().testOther("call other object func");
623      }
624  </script>
625  </body>
626  </html>
627  ```
628
629- Examples of using a promise:<br>
630  With the first method, a promise is created on the application side.
631  ```ts
632  // xxx.ets
633  import { webview } from '@kit.ArkWeb';
634  import { BusinessError } from '@kit.BasicServicesKit';
635
636  class testClass {
637    constructor() {
638    }
639
640    test(): Promise<string> {
641      let p: Promise<string> = new Promise((resolve, reject) => {
642        setTimeout(() => {
643          console.log ('Execution completed');
644          reject('fail');
645        }, 10000);
646      });
647      return p;
648    }
649
650    toString(param: String): void {
651      console.log(" " + param);
652    }
653  }
654
655  @Entry
656  @Component
657  struct Index {
658    webviewController: webview.WebviewController = new webview.WebviewController();
659    @State testObj: testClass = new testClass();
660
661    build() {
662      Column() {
663        Button('refresh')
664          .onClick(() => {
665            try {
666              this.webviewController.refresh();
667            } catch (error) {
668              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
669            }
670          })
671        Button('Register JavaScript To Window')
672          .onClick(() => {
673            try {
674              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
675            } catch (error) {
676              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
677            }
678          })
679        Button('deleteJavaScriptRegister')
680          .onClick(() => {
681            try {
682              this.webviewController.deleteJavaScriptRegister("testObjName");
683            } catch (error) {
684              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
685            }
686          })
687        Web({ src: $rawfile('index.html'), controller: this.webviewController })
688      }
689    }
690  }
691  ```
692
693  ```html
694  <!-- index.html -->
695  <!DOCTYPE html>
696  <html>
697  <body>
698  <button type="button" onclick="callArkTS()">Click Me!</button>
699  <p id="demo"></p>
700  <script>
701      function callArkTS() {
702        testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)})
703      }
704  </script>
705  </body>
706  </html>
707  ```
708  With the first method, a promise is created on the frontend page.
709  ```ts
710  // xxx.ets
711  import { webview } from '@kit.ArkWeb';
712  import { BusinessError } from '@kit.BasicServicesKit';
713
714  class testClass {
715    constructor() {
716    }
717
718    test(param:Function): void {
719      setTimeout( () => { param("suc") }, 10000)
720    }
721
722    toString(param:String): void {
723      console.log(" " + param);
724    }
725  }
726
727  @Entry
728  @Component
729  struct Index {
730    webviewController: webview.WebviewController = new webview.WebviewController();
731    @State testObj: testClass = new testClass();
732
733    build() {
734      Column() {
735        Button('refresh')
736          .onClick(() => {
737            try {
738              this.webviewController.refresh();
739            } catch (error) {
740              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
741            }
742          })
743        Button('Register JavaScript To Window')
744          .onClick(() => {
745            try {
746              this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);
747            } catch (error) {
748              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
749            }
750          })
751        Button('deleteJavaScriptRegister')
752          .onClick(() => {
753            try {
754              this.webviewController.deleteJavaScriptRegister("testObjName");
755            } catch (error) {
756              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
757            }
758          })
759        Web({ src: $rawfile('index.html'), controller: this.webviewController })
760      }
761    }
762  }
763  ```
764
765  ```html
766  <!-- index.html -->
767  <!DOCTYPE html>
768  <html>
769  <body>
770  <button type="button" onclick="callArkTS()">Click Me!</button>
771  <p id="demo"></p>
772  <script>
773      function callArkTS() {
774        let funpromise
775        var p = new Promise(function(resolve, reject){funpromise=(param)=>{resolve(param)}})
776        testObjName.test(funpromise)
777        p.then((param)=>{testObjName.toString(param)})
778      }
779  </script>
780  </body>
781  </html>
782  ```
783