• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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```