1# Interface (WebMessagePort) 2<!--Kit: ArkWeb--> 3<!--Subsystem: Web--> 4<!--Owner: @aohui--> 5<!--Designer: @yaomingliu--> 6<!--Tester: @ghiker--> 7<!--Adviser: @HelloCrease--> 8 9通过WebMessagePort可以进行消息的发送以及接收,发送[WebMessageType](./arkts-apis-webview-e.md#webmessagetype10)/[WebMessage](./arkts-apis-webview-t.md#webmessage)类型消息给HTML5侧。 10 11> **说明:** 12> 13> - 本模块首批接口从API version 9开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 14> 15> - 本Interface首批接口从API version 9开始支持。 16> 17> - 示例效果请以真机运行为准,当前DevEco Studio预览器不支持。 18 19## 导入模块 20 21```ts 22import { webview } from '@kit.ArkWeb'; 23``` 24 25## 属性 26 27**系统能力:** SystemCapability.Web.Webview.Core 28 29| 名称 | 类型 | 只读 | 可选 | 说明 | 30| ------------ | ------ | ---- | ---- | ------------------------------------------------| 31| isExtentionType<sup>10+</sup> | boolean | 否 | 是 | 创建WebMessagePort时是否指定使用扩展增强接口,[postMessageEventExt](#postmessageeventext10)、[onMessageEventExt](#onmessageeventext10)。<br>true表示使用扩展增强接口,false表示不使用扩展增强接口。<br>默认值:false。 | 32 33## postMessageEvent 34 35postMessageEvent(message: WebMessage): void 36 37发送[WebMessage](./arkts-apis-webview-t.md#webmessage)类型消息给HTML5侧,必须先调用[onMessageEvent](#onmessageevent),否则会发送失败。完整示例代码参考[postMessage](./arkts-apis-webview-WebviewController.md#postmessage)。 38 39**系统能力:** SystemCapability.Web.Webview.Core 40 41**参数:** 42 43| 参数名 | 类型 | 必填 | 说明 | 44| ------- | ------ | ---- | :------------- | 45| message | [WebMessage](./arkts-apis-webview-t.md#webmessage) | 是 | 要发送的消息。 | 46 47**错误码:** 48 49以下错误码的详细介绍请参见[webview错误码](errorcode-webview.md)。 50 51| 错误码ID | 错误信息 | 52| -------- | ------------------------------------- | 53| 17100010 | Failed to post messages through the port. | 54| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified. 2. Incorrect parameter types. 3.Parameter verification failed. | 55 56**示例:** 57 58```ts 59// xxx.ets 60import { webview } from '@kit.ArkWeb'; 61import { BusinessError } from '@kit.BasicServicesKit'; 62 63@Entry 64@Component 65struct WebComponent { 66 controller: webview.WebviewController = new webview.WebviewController(); 67 ports: webview.WebMessagePort[] = []; 68 69 build() { 70 Column() { 71 Button('postMessageEvent') 72 .onClick(() => { 73 try { 74 this.ports = this.controller.createWebMessagePorts(); 75 this.controller.postMessage('__init_port__', [this.ports[0]], '*'); 76 this.ports[1].postMessageEvent("post message from ets to html5"); 77 } catch (error) { 78 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 79 } 80 }) 81 Web({ src: 'www.example.com', controller: this.controller }) 82 } 83 } 84} 85``` 86 87## onMessageEvent 88 89onMessageEvent(callback: (result: WebMessage) => void): void 90 91在应用侧的消息端口上注册回调函数,接收HTML5侧发送过来的[WebMessage](./arkts-apis-webview-t.md#webmessage)类型消息。完整示例代码参考[postMessage](./arkts-apis-webview-WebviewController.md#postmessage)。 92 93**系统能力:** SystemCapability.Web.Webview.Core 94 95**参数:** 96 97| 参数名 | 类型 | 必填 | 说明 | 98| -------- | -------- | ---- | :------------------- | 99| callback | (result: [WebMessage](./arkts-apis-webview-t.md#webmessage)) => void | 是 | 接收到的消息。 | 100 101**错误码:** 102 103以下错误码的详细介绍请参见[webview错误码](errorcode-webview.md)。 104 105| 错误码ID | 错误信息 | 106| -------- | ----------------------------------------------- | 107| 17100006 | Failed to register a message event for the port.| 108| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified. 2. Incorrect parameter types. 3.Parameter verification failed.| 109 110**示例:** 111 112```ts 113// xxx.ets 114import { webview } from '@kit.ArkWeb'; 115import { BusinessError } from '@kit.BasicServicesKit'; 116 117@Entry 118@Component 119struct WebComponent { 120 controller: webview.WebviewController = new webview.WebviewController(); 121 ports: webview.WebMessagePort[] = []; 122 123 build() { 124 Column() { 125 Button('onMessageEvent') 126 .onClick(() => { 127 try { 128 this.ports = this.controller.createWebMessagePorts(); 129 this.ports[1].onMessageEvent((msg) => { 130 if (typeof (msg) == "string") { 131 console.info("received string message from html5, string is:" + msg); 132 } else if (typeof (msg) == "object") { 133 if (msg instanceof ArrayBuffer) { 134 console.info("received arraybuffer from html5, length is:" + msg.byteLength); 135 } else { 136 console.info("not support"); 137 } 138 } else { 139 console.info("not support"); 140 } 141 }) 142 } catch (error) { 143 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 144 } 145 }) 146 Web({ src: 'www.example.com', controller: this.controller }) 147 } 148 } 149} 150``` 151 152## postMessageEventExt<sup>10+</sup> 153 154postMessageEventExt(message: WebMessageExt): void 155 156发送[WebMessageType](./arkts-apis-webview-e.md#webmessagetype10)类型消息给HTML5侧,必须先调用[onMessageEventExt](#onmessageeventext10),否则会发送失败。完整示例代码参考[onMessageEventExt](#onmessageeventext10)。 157 158**系统能力:** SystemCapability.Web.Webview.Core 159 160**参数:** 161 162| 参数名 | 类型 | 必填 | 说明 | 163| ------- | ------ | ---- | :------------- | 164| message | [WebMessageExt](./arkts-apis-webview-WebMessageExt.md) | 是 | 要发送的消息。 | 165 166**错误码:** 167 168以下错误码的详细介绍请参见[webview错误码](errorcode-webview.md)。 169 170| 错误码ID | 错误信息 | 171| -------- | ------------------------------------- | 172| 17100010 | Failed to post messages through the port. | 173| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified. 2. Incorrect parameter types. 3.Parameter verification failed. | 174 175## onMessageEventExt<sup>10+</sup> 176 177onMessageEventExt(callback: (result: WebMessageExt) => void): void 178 179在应用侧的消息端口上注册回调函数,接收HTML5侧发送过来的[WebMessageType](./arkts-apis-webview-e.md#webmessagetype10)类型消息。 180 181**系统能力:** SystemCapability.Web.Webview.Core 182 183**参数:** 184 185| 参数名 | 类型 | 必填 | 说明 | 186| -------- | -------- | ---- | :------------------- | 187| callback | (result: [WebMessageExt](./arkts-apis-webview-WebMessageExt.md)) => void | 是 | 接收到的消息。 | 188 189**错误码:** 190 191以下错误码的详细介绍请参见[webview错误码](errorcode-webview.md)。 192 193| 错误码ID | 错误信息 | 194| -------- | ----------------------------------------------- | 195| 17100006 | Failed to register a message event for the port. | 196| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified. 2. Incorrect parameter types. 3.Parameter verification failed. | 197 198**示例:** 199 200```ts 201// xxx.ets 202import { webview } from '@kit.ArkWeb'; 203import { BusinessError } from '@kit.BasicServicesKit'; 204 205class TestObj { 206 test(str: string): ArrayBuffer { 207 let buf = new ArrayBuffer(str.length); 208 let buff = new Uint8Array(buf); 209 210 for (let i = 0; i < str.length; i++) { 211 buff[i] = str.charCodeAt(i); 212 } 213 return buf; 214 } 215} 216 217// 应用与网页互发消息的示例:使用"init_web_messageport"的通道,通过端口0在应用侧接受网页发送的消息,通过端口1在网页侧接受应用发送的消息。 218@Entry 219@Component 220struct WebComponent { 221 controller: webview.WebviewController = new webview.WebviewController(); 222 ports: webview.WebMessagePort[] = []; 223 nativePort: webview.WebMessagePort | null = null; 224 @State msg1: string = ""; 225 @State msg2: string = ""; 226 message: webview.WebMessageExt = new webview.WebMessageExt(); 227 @State testObjtest: TestObj = new TestObj(); 228 229 build() { 230 Column() { 231 Text(this.msg1).fontSize(16) 232 Text(this.msg2).fontSize(16) 233 Button('SendToH5 setString').margin({ 234 right: 800, 235 }) 236 .onClick(() => { 237 // 使用本侧端口发送消息给HTML5 238 try { 239 console.info("In ArkTS side send true start"); 240 if (this.nativePort) { 241 this.message.setType(1); 242 this.message.setString("helloFromEts"); 243 this.nativePort.postMessageEventExt(this.message); 244 } 245 } 246 catch (error) { 247 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 248 } 249 }) 250 Button('SendToH5 setNumber').margin({ 251 top: 10, 252 right: 800, 253 }) 254 .onClick(() => { 255 // 使用本侧端口发送消息给HTML5 256 try { 257 console.info("In ArkTS side send true start"); 258 if (this.nativePort) { 259 this.message.setType(2); 260 this.message.setNumber(12345); 261 this.nativePort.postMessageEventExt(this.message); 262 } 263 } 264 catch (error) { 265 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 266 } 267 }) 268 Button('SendToH5 setBoolean').margin({ 269 top: -90, 270 }) 271 .onClick(() => { 272 // 使用本侧端口发送消息给HTML5 273 try { 274 console.info("In ArkTS side send true start"); 275 if (this.nativePort) { 276 this.message.setType(3); 277 this.message.setBoolean(true); 278 this.nativePort.postMessageEventExt(this.message); 279 } 280 } 281 catch (error) { 282 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 283 } 284 }) 285 Button('SendToH5 setArrayBuffer').margin({ 286 top: 10, 287 }) 288 .onClick(() => { 289 // 使用本侧端口发送消息给HTML5 290 try { 291 console.info("In ArkTS side send true start"); 292 if (this.nativePort) { 293 this.message.setType(4); 294 this.message.setArrayBuffer(this.testObjtest.test("Name=test&Password=test")); 295 this.nativePort.postMessageEventExt(this.message); 296 } 297 } 298 catch (error) { 299 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 300 } 301 }) 302 Button('SendToH5 setArray').margin({ 303 top: -90, 304 left: 800, 305 }) 306 .onClick(() => { 307 // 使用本侧端口发送消息给HTML5 308 try { 309 console.info("In ArkTS side send true start"); 310 if (this.nativePort) { 311 this.message.setType(5); 312 this.message.setArray([1, 2, 3]); 313 this.nativePort.postMessageEventExt(this.message); 314 } 315 } 316 catch (error) { 317 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 318 } 319 }) 320 Button('SendToH5 setError').margin({ 321 top: 10, 322 left: 800, 323 }) 324 .onClick(() => { 325 // 使用本侧端口发送消息给HTML5 326 try { 327 console.info("In ArkTS side send true start"); 328 throw new ReferenceError("ReferenceError"); 329 } 330 catch (error) { 331 if (this.nativePort) { 332 this.message.setType(6); 333 this.message.setError(error); 334 this.nativePort.postMessageEventExt(this.message); 335 } 336 console.error(`In ArkTS side send message catch error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 337 } 338 }) 339 340 Web({ src: $rawfile('index.html'), controller: this.controller }) 341 .onPageEnd(() => { 342 console.info("In ArkTS side message onPageEnd init message channel"); 343 // 1. 创建消息端口 344 this.ports = this.controller.createWebMessagePorts(true); 345 // 2. 发送端口1到HTML5 346 this.controller.postMessage("init_web_messageport", [this.ports[1]], "*"); 347 // 3. 保存端口0到本地 348 this.nativePort = this.ports[0]; 349 // 4. 设置回调函数 350 this.nativePort.onMessageEventExt((result) => { 351 console.info("In ArkTS side got message"); 352 try { 353 let type = result.getType(); 354 console.info("In ArkTS side getType:" + type); 355 switch (type) { 356 case webview.WebMessageType.STRING: { 357 this.msg1 = "result type:" + typeof (result.getString()); 358 this.msg2 = "result getString:" + ((result.getString())); 359 break; 360 } 361 case webview.WebMessageType.NUMBER: { 362 this.msg1 = "result type:" + typeof (result.getNumber()); 363 this.msg2 = "result getNumber:" + ((result.getNumber())); 364 break; 365 } 366 case webview.WebMessageType.BOOLEAN: { 367 this.msg1 = "result type:" + typeof (result.getBoolean()); 368 this.msg2 = "result getBoolean:" + ((result.getBoolean())); 369 break; 370 } 371 case webview.WebMessageType.ARRAY_BUFFER: { 372 this.msg1 = "result type:" + typeof (result.getArrayBuffer()); 373 this.msg2 = "result getArrayBuffer byteLength:" + ((result.getArrayBuffer().byteLength)); 374 break; 375 } 376 case webview.WebMessageType.ARRAY: { 377 this.msg1 = "result type:" + typeof (result.getArray()); 378 this.msg2 = "result getArray:" + result.getArray(); 379 break; 380 } 381 case webview.WebMessageType.ERROR: { 382 this.msg1 = "result type:" + typeof (result.getError()); 383 this.msg2 = "result getError:" + result.getError(); 384 break; 385 } 386 default: { 387 this.msg1 = "default break, type:" + type; 388 break; 389 } 390 } 391 } 392 catch (error) { 393 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 394 } 395 }); 396 }) 397 } 398 } 399} 400``` 401 402加载的html文件。 403```html 404<!--index.html--> 405<!DOCTYPE html> 406<html lang="en-gb"> 407<head> 408 <title>WebView MessagePort Demo</title> 409</head> 410 411<body> 412<h1>Html5 Send and Receive Message</h1> 413<h3 id="msg">Receive string:</h3> 414<h3 id="msg2">Receive arraybuffer:</h3> 415<div style="font-size: 10pt; text-align: center;"> 416 <input type="button" value="Send String" onclick="postStringToApp();" /><br/> 417</div> 418</body> 419<script src="index.js"></script> 420</html> 421``` 422 423<!--code_no_check--> 424```js 425//index.js 426var h5Port; 427window.addEventListener('message', function(event) { 428 if (event.data == 'init_web_messageport') { 429 if(event.ports[0] != null) { 430 h5Port = event.ports[0]; // 1. 保存从ets侧发送过来的端口 431 h5Port.onmessage = function(event) { 432 console.info("hwd In html got message"); 433 // 2. 接收ets侧发送过来的消息. 434 var result = event.data; 435 console.info("In html got message, typeof: ", typeof(result)); 436 console.info("In html got message, result: ", (result)); 437 if (typeof(result) == "string") { 438 console.info("In html got message, String: ", result); 439 document.getElementById("msg").innerHTML = "String:" + result; 440 } else if (typeof(result) == "number") { 441 console.info("In html side got message, number: ", result); 442 document.getElementById("msg").innerHTML = "Number:" + result; 443 } else if (typeof(result) == "boolean") { 444 console.info("In html side got message, boolean: ", result); 445 document.getElementById("msg").innerHTML = "Boolean:" + result; 446 } else if (typeof(result) == "object") { 447 if (result instanceof ArrayBuffer) { 448 document.getElementById("msg2").innerHTML = "ArrayBuffer:" + result.byteLength; 449 console.info("In html got message, byteLength: ", result.byteLength); 450 } else if (result instanceof Error) { 451 console.info("In html error message, err:" + (result)); 452 console.info("In html error message, typeof err:" + typeof(result)); 453 document.getElementById("msg2").innerHTML = "Error:" + result.name + ", msg:" + result.message; 454 } else if (result instanceof Array) { 455 console.info("In html got message, Array"); 456 console.info("In html got message, Array length:" + result.length); 457 console.info("In html got message, Array[0]:" + (result[0])); 458 console.info("In html got message, typeof Array[0]:" + typeof(result[0])); 459 document.getElementById("msg2").innerHTML = "Array len:" + result.length + ", value:" + result; 460 } else { 461 console.info("In html got message, not any instance of support type"); 462 document.getElementById("msg").innerHTML = "not any instance of support type"; 463 } 464 } else { 465 console.info("In html got message, not support type"); 466 document.getElementById("msg").innerHTML = "not support type"; 467 } 468 } 469 h5Port.onmessageerror = (event) => { 470 console.error(`hwd In html Error receiving message: ${event}`); 471 }; 472 } 473 } 474}) 475 476// 使用h5Port往ets侧发送String类型的消息. 477function postStringToApp() { 478 if (h5Port) { 479 console.info("In html send string message"); 480 h5Port.postMessage("hello"); 481 console.info("In html send string message end"); 482 } else { 483 console.error("In html h5port is null, please init first"); 484 } 485} 486``` 487 488## close 489 490close(): void 491 492不需要发送消息时关闭该消息端口。在使用close前,请先使用[createWebMessagePorts](./arkts-apis-webview-WebviewController.md#createwebmessageports)创建消息端口。 493 494**系统能力:** SystemCapability.Web.Webview.Core 495 496**示例:** 497 498```ts 499// xxx.ets 500import { webview } from '@kit.ArkWeb'; 501import { BusinessError } from '@kit.BasicServicesKit'; 502 503@Entry 504@Component 505struct WebComponent { 506 controller: webview.WebviewController = new webview.WebviewController(); 507 msgPort: webview.WebMessagePort[] = []; 508 509 build() { 510 Column() { 511 // 先使用createWebMessagePorts创建端口。 512 Button('createWebMessagePorts') 513 .onClick(() => { 514 try { 515 this.msgPort = this.controller.createWebMessagePorts(); 516 console.info("createWebMessagePorts size:" + this.msgPort.length) 517 } catch (error) { 518 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 519 } 520 }) 521 Button('close') 522 .onClick(() => { 523 try { 524 if (this.msgPort && this.msgPort.length == 2) { 525 this.msgPort[1].close(); 526 } else { 527 console.error("msgPort is null, Please initialize first"); 528 } 529 } catch (error) { 530 console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 531 } 532 }) 533 Web({ src: 'www.example.com', controller: this.controller }) 534 } 535 } 536} 537```