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