1# 建立应用侧与前端页面数据通道
2
3
4前端页面和应用侧之间可以用[createWebMessagePorts()](../reference/apis-arkweb/js-apis-webview.md#createwebmessageports)接口创建消息端口来实现两端的通信。
5
6
7在下面的示例中,应用侧页面中通过createWebMessagePorts方法创建消息端口,再把其中一个端口通过[postMessage()](../reference/apis-arkweb/js-apis-webview.md#postmessage)接口发送到前端页面,便可以在前端页面和应用侧之间互相发送消息。
8
9
10- 应用侧代码。
11
12  ```ts
13  // xxx.ets
14  import { webview } from '@kit.ArkWeb';
15  import { BusinessError } from '@kit.BasicServicesKit';
16
17  @Entry
18  @Component
19  struct WebComponent {
20    controller: webview.WebviewController = new webview.WebviewController();
21    ports: webview.WebMessagePort[] = [];
22    @State sendFromEts: string = 'Send this message from ets to HTML';
23    @State receivedFromHtml: string = 'Display received message send from HTML';
24
25    build() {
26      Column() {
27        // 展示接收到的来自HTML的内容
28        Text(this.receivedFromHtml)
29        // 输入框的内容发送到HTML
30        TextInput({ placeholder: 'Send this message from ets to HTML' })
31          .onChange((value: string) => {
32            this.sendFromEts = value;
33          })
34
35        // 该内容可以放在onPageEnd生命周期中调用。
36        Button('postMessage')
37          .onClick(() => {
38            try {
39              // 1、创建两个消息端口。
40              this.ports = this.controller.createWebMessagePorts();
41              // 2、在应用侧的消息端口(如端口1)上注册回调事件。
42              this.ports[1].onMessageEvent((result: webview.WebMessage) => {
43                let msg = 'Got msg from HTML:';
44                if (typeof (result) === 'string') {
45                  console.info(`received string message from html5, string is: ${result}`);
46                  msg = msg + result;
47                } else if (typeof (result) === 'object') {
48                  if (result instanceof ArrayBuffer) {
49                    console.info(`received arraybuffer from html5, length is: ${result.byteLength}`);
50                    msg = msg + 'length is ' + result.byteLength;
51                  } else {
52                    console.info('not support');
53                  }
54                } else {
55                  console.info('not support');
56                }
57                this.receivedFromHtml = msg;
58              })
59              // 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
60              this.controller.postMessage('__init_port__', [this.ports[0]], '*');
61            } catch (error) {
62              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
63            }
64          })
65
66        // 4、使用应用侧的端口给另一个已经发送到html的端口发送消息。
67        Button('SendDataToHTML')
68          .onClick(() => {
69            try {
70              if (this.ports && this.ports[1]) {
71                this.ports[1].postMessageEvent(this.sendFromEts);
72              } else {
73                console.error(`ports is null, Please initialize first`);
74              }
75            } catch (error) {
76              console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
77            }
78          })
79        Web({ src: $rawfile('index.html'), controller: this.controller })
80      }
81    }
82  }
83  ```
84
85- 前端页面代码。
86
87  ```html
88  <!--index.html-->
89  <!DOCTYPE html>
90  <html>
91  <head>
92      <meta name="viewport" content="width=device-width, initial-scale=1.0">
93      <title>WebView Message Port Demo</title>
94  </head>
95  <body>
96      <h1>WebView Message Port Demo</h1>
97      <div>
98          <input type="button" value="SendToEts" onclick="PostMsgToEts(msgFromJS.value);"/><br/>
99          <input id="msgFromJS" type="text" value="send this message from HTML to ets"/><br/>
100      </div>
101      <p class="output">display received message send from ets</p>
102  </body>
103  <script>
104  var h5Port;
105  var output = document.querySelector('.output');
106  window.addEventListener('message', function (event) {
107      if (event.data === '__init_port__') {
108          if (event.ports[0] !== null) {
109              h5Port = event.ports[0]; // 1. 保存从应用侧发送过来的端口。
110              h5Port.onmessage = function (event) {
111                // 2. 接收ets侧发送过来的消息。
112                var msg = 'Got message from ets:';
113                var result = event.data;
114                if (typeof(result) === 'string') {
115                  console.info(`received string message from html5, string is: ${result}`);
116                  msg = msg + result;
117                } else if (typeof(result) === 'object') {
118                  if (result instanceof ArrayBuffer) {
119                    console.info(`received arraybuffer from html5, length is: ${result.byteLength}`);
120                    msg = msg + 'length is ' + result.byteLength;
121                  } else {
122                    console.info('not support');
123                  }
124                } else {
125                  console.info('not support');
126                }
127                output.innerHTML = msg;
128              }
129          }
130      }
131  })
132
133  // 3. 使用h5Port向应用侧发送消息。
134  function PostMsgToEts(data) {
135      if (h5Port) {
136        h5Port.postMessage(data);
137      } else {
138        console.error('h5Port is null, Please initialize first');
139      }
140  }
141  </script>
142  </html>
143  ```
144