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