1# 前端页面调用应用侧函数 2 3 4开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。 5 6 7注册应用侧代码有两种方式,一种在Web组件初始化调用,使用[javaScriptProxy()](../reference/apis-arkweb/ts-basic-components-web.md#javascriptproxy)接口。另外一种在Web组件初始化完成后调用,使用[registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy)接口, 需要和[deleteJavaScriptRegister](../reference/apis-arkweb/js-apis-webview.md#deletejavascriptregister)接口配合使用,防止内存泄漏。 8 9 10在下面的示例中,将test()方法注册在前端页面中, 该函数可以在前端页面触发运行。 11 12 13- [javaScriptProxy()](../reference/apis-arkweb/ts-basic-components-web.md#javascriptproxy)接口使用示例如下。 14 15 ```ts 16 // xxx.ets 17 import { webview } from '@kit.ArkWeb'; 18 import { BusinessError } from '@kit.BasicServicesKit'; 19 20 class testClass { 21 constructor() { 22 } 23 24 test(): string { 25 return 'ArkTS Hello World!'; 26 } 27 } 28 29 @Entry 30 @Component 31 struct WebComponent { 32 webviewController: webview.WebviewController = new webview.WebviewController(); 33 // 声明需要注册的对象 34 @State testObj: testClass = new testClass(); 35 36 build() { 37 Column() { 38 Button('deleteJavaScriptRegister') 39 .onClick(() => { 40 try { 41 this.webviewController.deleteJavaScriptRegister("testObjName"); 42 } catch (error) { 43 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 44 } 45 }) 46 // Web组件加载本地index.html页面 47 Web({ src: $rawfile('index.html'), controller: this.webviewController}) 48 // 将对象注入到web端 49 .javaScriptProxy({ 50 object: this.testObj, 51 name: "testObjName", 52 methodList: ["test"], 53 controller: this.webviewController, 54 // 可选参数 55 asyncMethodList: [], 56 permission: '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' + 57 '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' + 58 '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' + 59 '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' + 60 '{"scheme":"u","host":"v","port":"","path":""}]}]}}' 61 }) 62 } 63 } 64 } 65 ``` 66 67 68- 应用侧使用[registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy)接口注册。 69 70 ```ts 71 // xxx.ets 72 import { webview } from '@kit.ArkWeb'; 73 import { BusinessError } from '@kit.BasicServicesKit'; 74 75 class testClass { 76 constructor() { 77 } 78 79 test(): string { 80 return "ArkUI Web Component"; 81 } 82 83 toString(): void { 84 console.log('Web Component toString'); 85 } 86 } 87 88 @Entry 89 @Component 90 struct Index { 91 webviewController: webview.WebviewController = new webview.WebviewController(); 92 @State testObj: testClass = new testClass(); 93 94 build() { 95 Column() { 96 Button('refresh') 97 .onClick(() => { 98 try { 99 this.webviewController.refresh(); 100 } catch (error) { 101 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 102 } 103 }) 104 Button('Register JavaScript To Window') 105 .onClick(() => { 106 try { 107 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"], 108 // 可选参数, asyncMethodList 109 [], 110 // 可选参数, permission 111 '{"javascriptProxyPermission":{"urlPermissionList":[{"scheme":"resource","host":"rawfile","port":"","path":""},' + 112 '{"scheme":"e","host":"f","port":"g","path":"h"}],"methodList":[{"methodName":"test","urlPermissionList":' + 113 '[{"scheme":"https","host":"xxx.com","port":"","path":""},{"scheme":"resource","host":"rawfile","port":"","path":""}]},' + 114 '{"methodName":"test11","urlPermissionList":[{"scheme":"q","host":"r","port":"","path":"t"},' + 115 '{"scheme":"u","host":"v","port":"","path":""}]}]}}' 116 ); 117 } catch (error) { 118 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 119 } 120 }) 121 Button('deleteJavaScriptRegister') 122 .onClick(() => { 123 try { 124 this.webviewController.deleteJavaScriptRegister("testObjName"); 125 } catch (error) { 126 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 127 } 128 }) 129 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 130 } 131 } 132 } 133 ``` 134 135 > **说明:** 136 > 137 > - 使用[registerJavaScriptProxy()](../reference/apis-arkweb/js-apis-webview.md#registerjavascriptproxy)接口注册方法时,注册后需调用[refresh()](../reference/apis-arkweb/js-apis-webview.md#refresh)接口生效。 138 139- 可选参数permission是一个json字符串,示例如下: 140 ```json 141 { 142 "javascriptProxyPermission": { 143 "urlPermissionList": [ // Object级权限,如果匹配,所有Method都授权 144 { 145 "scheme": "resource", // 精确匹配,不能为空 146 "host": "rawfile", // 精确匹配,不能为空 147 "port": "", // 精确匹配,为空不检查 148 "path": "" // 前缀匹配,为空不检查 149 }, 150 { 151 "scheme": "https", // 精确匹配,不能为空 152 "host": "xxx.com", // 精确匹配,不能为空 153 "port": "8080", // 精确匹配,为空不检查 154 "path": "a/b/c" // 前缀匹配,为空不检查 155 } 156 ], 157 "methodList": [ 158 { 159 "methodName": "test", 160 "urlPermissionList": [ // Method级权限 161 { 162 "scheme": "https", // 精确匹配,不能为空 163 "host": "xxx.com", // 精确匹配,不能为空 164 "port": "", // 精确匹配,为空不检查 165 "path": "" // 前缀匹配,为空不检查 166 }, 167 { 168 "scheme": "resource",// 精确匹配,不能为空 169 "host": "rawfile", // 精确匹配,不能为空 170 "port": "", // 精确匹配,为空不检查 171 "path": "" // 前缀匹配,为空不检查 172 } 173 ] 174 }, 175 { 176 "methodName": "test11", 177 "urlPermissionList": [ // Method级权限 178 { 179 "scheme": "q", // 精确匹配,不能为空 180 "host": "r", // 精确匹配,不能为空 181 "port": "", // 精确匹配,为空不检查 182 "path": "t" // 前缀匹配,为空不检查 183 }, 184 { 185 "scheme": "u", // 精确匹配,不能为空 186 "host": "v", // 精确匹配,不能为空 187 "port": "", // 精确匹配,为空不检查 188 "path": "" // 前缀匹配,为空不检查 189 } 190 ] 191 } 192 ] 193 } 194 } 195 ``` 196 197- index.html前端页面触发应用侧代码。 198 199 ```html 200 <!-- index.html --> 201 <!DOCTYPE html> 202 <html> 203 <body> 204 <button type="button" onclick="callArkTS()">Click Me!</button> 205 <p id="demo"></p> 206 <script> 207 function callArkTS() { 208 let str = testObjName.test(); 209 document.getElementById("demo").innerHTML = str; 210 console.info('ArkTS Hello World! :' + str); 211 } 212 </script> 213 </body> 214 </html> 215 ``` 216## 复杂类型使用方法 217- 应用侧和前端页面之间传递Array。 218 ```ts 219 // xxx.ets 220 import { webview } from '@kit.ArkWeb'; 221 import { BusinessError } from '@kit.BasicServicesKit'; 222 223 class testClass { 224 constructor() { 225 } 226 227 test(): Array<Number> { 228 return [1, 2, 3, 4] 229 } 230 231 toString(param: String): void { 232 console.log('Web Component toString' + param); 233 } 234 } 235 236 @Entry 237 @Component 238 struct Index { 239 webviewController: webview.WebviewController = new webview.WebviewController(); 240 @State testObj: testClass = new testClass(); 241 242 build() { 243 Column() { 244 Button('refresh') 245 .onClick(() => { 246 try { 247 this.webviewController.refresh(); 248 } catch (error) { 249 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 250 } 251 }) 252 Button('Register JavaScript To Window') 253 .onClick(() => { 254 try { 255 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 256 } catch (error) { 257 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 258 } 259 }) 260 Button('deleteJavaScriptRegister') 261 .onClick(() => { 262 try { 263 this.webviewController.deleteJavaScriptRegister("testObjName"); 264 } catch (error) { 265 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 266 } 267 }) 268 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 269 } 270 } 271 } 272 ``` 273 274 ```html 275 <!-- index.html --> 276 <!DOCTYPE html> 277 <html> 278 <body> 279 <button type="button" onclick="callArkTS()">Click Me!</button> 280 <p id="demo"></p> 281 <script> 282 function callArkTS() { 283 testObjName.toString(testObjName.test()); 284 } 285 </script> 286 </body> 287 </html> 288 ``` 289- 应用侧和前端页面之间传递基础类型,非Function等复杂类型。 290 ```ts 291 // xxx.ets 292 import { webview } from '@kit.ArkWeb'; 293 import { BusinessError } from '@kit.BasicServicesKit'; 294 295 class student { 296 name: string = ''; 297 age: string = ''; 298 } 299 300 class testClass { 301 constructor() { 302 } 303 304 // 传递的基础类型name:"jeck", age:"12"。 305 test(): student { 306 let st: student = { name: "jeck", age: "12" }; 307 return st; 308 } 309 310 toString(param: ESObject): void { 311 console.log('Web Component toString' + param["name"]); 312 } 313 } 314 315 @Entry 316 @Component 317 struct Index { 318 webviewController: webview.WebviewController = new webview.WebviewController(); 319 @State testObj: testClass = new testClass(); 320 321 build() { 322 Column() { 323 Button('refresh') 324 .onClick(() => { 325 try { 326 this.webviewController.refresh(); 327 } catch (error) { 328 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 329 } 330 }) 331 Button('Register JavaScript To Window') 332 .onClick(() => { 333 try { 334 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 335 } catch (error) { 336 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 337 } 338 }) 339 Button('deleteJavaScriptRegister') 340 .onClick(() => { 341 try { 342 this.webviewController.deleteJavaScriptRegister("testObjName"); 343 } catch (error) { 344 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 345 } 346 }) 347 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 348 } 349 } 350 } 351 ``` 352 353 ```html 354 <!-- index.html --> 355 <!DOCTYPE html> 356 <html> 357 <body> 358 <button type="button" onclick="callArkTS()">Click Me!</button> 359 <p id="demo"></p> 360 <script> 361 function callArkTS() { 362 testObjName.toString(testObjName.test()); 363 } 364 </script> 365 </body> 366 </html> 367 ``` 368 369- 应用侧调用前端页面的Callback。 370 ```ts 371 // xxx.ets 372 import { webview } from '@kit.ArkWeb'; 373 import { BusinessError } from '@kit.BasicServicesKit'; 374 375 class testClass { 376 constructor() { 377 } 378 379 test(param: Function): void { 380 param("call callback"); 381 } 382 383 toString(param: String): void { 384 console.log('Web Component toString' + param); 385 } 386 } 387 388 @Entry 389 @Component 390 struct Index { 391 webviewController: webview.WebviewController = new webview.WebviewController(); 392 @State testObj: testClass = new testClass(); 393 394 build() { 395 Column() { 396 Button('refresh') 397 .onClick(() => { 398 try { 399 this.webviewController.refresh(); 400 } catch (error) { 401 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 402 } 403 }) 404 Button('Register JavaScript To Window') 405 .onClick(() => { 406 try { 407 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 408 } catch (error) { 409 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 410 } 411 }) 412 Button('deleteJavaScriptRegister') 413 .onClick(() => { 414 try { 415 this.webviewController.deleteJavaScriptRegister("testObjName"); 416 } catch (error) { 417 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 418 } 419 }) 420 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 421 } 422 } 423 } 424 ``` 425 426 ```html 427 <!-- index.html --> 428 <!DOCTYPE html> 429 <html> 430 <body> 431 <button type="button" onclick="callArkTS()">Click Me!</button> 432 <p id="demo"></p> 433 <script> 434 function callArkTS() { 435 testObjName.test(function(param){testObjName.toString(param)}); 436 } 437 </script> 438 </body> 439 </html> 440 ``` 441 442- 应用侧调用前端页面Object里的Function。 443 ```ts 444 // xxx.ets 445 import { webview } from '@kit.ArkWeb'; 446 import { BusinessError } from '@kit.BasicServicesKit'; 447 448 class testClass { 449 constructor() { 450 } 451 452 test(param: ESObject): void { 453 param.hello("call obj func"); 454 } 455 456 toString(param: String): void { 457 console.log('Web Component toString' + param); 458 } 459 } 460 461 @Entry 462 @Component 463 struct Index { 464 webviewController: webview.WebviewController = new webview.WebviewController(); 465 @State testObj: testClass = new testClass(); 466 467 build() { 468 Column() { 469 Button('refresh') 470 .onClick(() => { 471 try { 472 this.webviewController.refresh(); 473 } catch (error) { 474 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 475 } 476 }) 477 Button('Register JavaScript To Window') 478 .onClick(() => { 479 try { 480 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 481 } catch (error) { 482 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 483 } 484 }) 485 Button('deleteJavaScriptRegister') 486 .onClick(() => { 487 try { 488 this.webviewController.deleteJavaScriptRegister("testObjName"); 489 } catch (error) { 490 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 491 } 492 }) 493 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 494 } 495 } 496 } 497 ``` 498 499 ```html 500 <!-- index.html --> 501 <!DOCTYPE html> 502 <html> 503 <body> 504 <button type="button" onclick="callArkTS()">Click Me!</button> 505 <p id="demo"></p> 506 <script> 507 // 写法1 508 class Student { 509 constructor(nameList) { 510 this.methodNameListForJsProxy = nameList; 511 } 512 513 hello(param) { 514 testObjName.toString(param) 515 } 516 } 517 var st = new Student(["hello"]) 518 519 // 写法2 520 //创建一个构造器,构造函数首字母大写 521 function Obj1(){ 522 this.methodNameListForJsProxy=["hello"]; 523 this.hello=function(param){ 524 testObjName.toString(param) 525 }; 526 } 527 //利用构造器,通过new关键字生成对象 528 var st1 = new Obj1(); 529 530 function callArkTS() { 531 testObjName.test(st); 532 testObjName.test(st1); 533 } 534 </script> 535 </body> 536 </html> 537 ``` 538 539- 前端页面调用应用侧Object里的Function。 540 ```ts 541 // xxx.ets 542 import { webview } from '@kit.ArkWeb'; 543 import { BusinessError } from '@kit.BasicServicesKit'; 544 545 class ObjOther { 546 methodNameListForJsProxy: string[] 547 548 constructor(list: string[]) { 549 this.methodNameListForJsProxy = list 550 } 551 552 testOther(json: string): void { 553 console.info(json) 554 } 555 } 556 557 class testClass { 558 ObjReturn: ObjOther 559 560 constructor() { 561 this.ObjReturn = new ObjOther(["testOther"]); 562 } 563 564 test(): ESObject { 565 return this.ObjReturn 566 } 567 568 toString(param: string): void { 569 console.log('Web Component toString' + param); 570 } 571 } 572 573 @Entry 574 @Component 575 struct Index { 576 webviewController: webview.WebviewController = new webview.WebviewController(); 577 @State testObj: testClass = new testClass(); 578 579 build() { 580 Column() { 581 Button('refresh') 582 .onClick(() => { 583 try { 584 this.webviewController.refresh(); 585 } catch (error) { 586 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 587 } 588 }) 589 Button('Register JavaScript To Window') 590 .onClick(() => { 591 try { 592 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 593 } catch (error) { 594 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 595 } 596 }) 597 Button('deleteJavaScriptRegister') 598 .onClick(() => { 599 try { 600 this.webviewController.deleteJavaScriptRegister("testObjName"); 601 } catch (error) { 602 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 603 } 604 }) 605 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 606 } 607 } 608 } 609 ``` 610 611 ```html 612 <!-- index.html --> 613 <!DOCTYPE html> 614 <html> 615 <body> 616 <button type="button" onclick="callArkTS()">Click Me!</button> 617 <p id="demo"></p> 618 <script> 619 function callArkTS() { 620 testObjName.test().testOther("call other object func"); 621 } 622 </script> 623 </body> 624 </html> 625 ``` 626 627- Promise场景。<br> 628 第一种使用方法,在应用侧new Promise。 629 ```ts 630 // xxx.ets 631 import { webview } from '@kit.ArkWeb'; 632 import { BusinessError } from '@kit.BasicServicesKit'; 633 634 class testClass { 635 constructor() { 636 } 637 638 test(): Promise<string> { 639 let p: Promise<string> = new Promise((resolve, reject) => { 640 setTimeout(() => { 641 console.log('执行完成'); 642 reject('fail'); 643 }, 10000); 644 }); 645 return p; 646 } 647 648 toString(param: String): void { 649 console.log(" " + param); 650 } 651 } 652 653 @Entry 654 @Component 655 struct Index { 656 webviewController: webview.WebviewController = new webview.WebviewController(); 657 @State testObj: testClass = new testClass(); 658 659 build() { 660 Column() { 661 Button('refresh') 662 .onClick(() => { 663 try { 664 this.webviewController.refresh(); 665 } catch (error) { 666 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 667 } 668 }) 669 Button('Register JavaScript To Window') 670 .onClick(() => { 671 try { 672 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 673 } catch (error) { 674 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 675 } 676 }) 677 Button('deleteJavaScriptRegister') 678 .onClick(() => { 679 try { 680 this.webviewController.deleteJavaScriptRegister("testObjName"); 681 } catch (error) { 682 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 683 } 684 }) 685 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 686 } 687 } 688 } 689 ``` 690 691 ```html 692 <!-- index.html --> 693 <!DOCTYPE html> 694 <html> 695 <body> 696 <button type="button" onclick="callArkTS()">Click Me!</button> 697 <p id="demo"></p> 698 <script> 699 function callArkTS() { 700 testObjName.test().then((param)=>{testObjName.toString(param)}).catch((param)=>{testObjName.toString(param)}) 701 } 702 </script> 703 </body> 704 </html> 705 ``` 706 第二种使用方法,在前端页面new Promise。 707 ```ts 708 // xxx.ets 709 import { webview } from '@kit.ArkWeb'; 710 import { BusinessError } from '@kit.BasicServicesKit'; 711 712 class testClass { 713 constructor() { 714 } 715 716 test(param:Function): void { 717 setTimeout( () => { param("suc") }, 10000) 718 } 719 720 toString(param:String): void { 721 console.log(" " + param); 722 } 723 } 724 725 @Entry 726 @Component 727 struct Index { 728 webviewController: webview.WebviewController = new webview.WebviewController(); 729 @State testObj: testClass = new testClass(); 730 731 build() { 732 Column() { 733 Button('refresh') 734 .onClick(() => { 735 try { 736 this.webviewController.refresh(); 737 } catch (error) { 738 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 739 } 740 }) 741 Button('Register JavaScript To Window') 742 .onClick(() => { 743 try { 744 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]); 745 } catch (error) { 746 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 747 } 748 }) 749 Button('deleteJavaScriptRegister') 750 .onClick(() => { 751 try { 752 this.webviewController.deleteJavaScriptRegister("testObjName"); 753 } catch (error) { 754 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 755 } 756 }) 757 Web({ src: $rawfile('index.html'), controller: this.webviewController }) 758 } 759 } 760 } 761 ``` 762 763 ```html 764 <!-- index.html --> 765 <!DOCTYPE html> 766 <html> 767 <body> 768 <button type="button" onclick="callArkTS()">Click Me!</button> 769 <p id="demo"></p> 770 <script> 771 function callArkTS() { 772 let funpromise 773 var p = new Promise(function(resolve, reject){funpromise=(param)=>{resolve(param)}}) 774 testObjName.test(funpromise) 775 p.then((param)=>{testObjName.toString(param)}) 776 } 777 </script> 778 </body> 779 </html> 780 ``` 781