# web_view

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// xxx.ets
import web_webview from '@ohos.web.webview'

web_webview.once("webInited", () => {
console.log("setCookie")
web_webview.WebCookieManager.setCookie("https://www.example.com", "a=b")
})

@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();

build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
}
}
}

# MessagePort 进行双向通信

# 鸿蒙原生应用侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// xxx.ets
import web_webview from '@ohos.web.webview';

@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
ports: web_webview.WebMessagePort[];
@State sendFromEts: string = 'Send this message from ets to HTML';
@State receivedFromHtml: string = 'Display received message send from HTML';

build() {
Column() {
// 展示接收到的来自HTML的内容
Text(this.receivedFromHtml)
// 输入框的内容发送到html
TextInput({placeholder: 'Send this message from ets to HTML'})
.onChange((value: string) => {
this.sendFromEts = value;
})

Button('postMessage')
.onClick(() => {
try {
// 1、创建两个消息端口。
this.ports = this.controller.createWebMessagePorts();
// 2、在应用侧的消息端口(如端口1)上注册回调事件。
this.ports[1].onMessageEvent((result: web_webview.WebMessage) => {
let msg = 'Got msg from HTML:';
if (typeof(result) == "string") {
console.log("received string message from html5, string is:" + result);
msg = msg + result;
} else if (typeof(result) == "object") {
if (result instanceof ArrayBuffer) {
console.log("received arraybuffer from html5, length is:" + result.byteLength);
msg = msg + "lenght is " + result.byteLength;
} else {
console.log("not support");
}
} else {
console.log("not support");
}
this.receivedFromHtml = msg;
})
// 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。
this.controller.postMessage('__init_port__', [this.ports[0]], '*');
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})

// 4、使用应用侧的端口给另一个已经发送到html的端口发送消息。
Button('SendDataToHTML')
.onClick(() => {
try {
if (this.ports && this.ports[1]) {
this.ports[1].postMessageEvent(this.sendFromEts);
} else {
console.error(`ports is null, Please initialize first`);
}
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: $rawfile('index.html'), controller: this.controller })
}
}
}

# h5 侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebView Message Port Demo</title>
</head>

<body>
<h1>WebView Message Port Demo</h1>
<div>
<input type="button" value="SendToEts" onclick="PostMsgToEts(msgFromJS.value);"/><br/>
<input id="msgFromJS" type="text" value="send this message from HTML to ets"/><br/>
</div>
<p class="output">display received message send from ets</p>
</body>
<script src="xxx.js"></script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//xxx.js
var h5Port;
var output = document.querySelector('.output');
window.addEventListener('message', function (event) {
if (event.data == '__init_port__') {
if (event.ports[0] != null) {
h5Port = event.ports[0]; // 1. 保存从ets侧发送过来的端口
h5Port.onmessage = function (event) {
// 2. 接收ets侧发送过来的消息.
var msg = 'Got message from ets:';
var result = event.data;
if (typeof(result) == "string") {
console.log("received string message from html5, string is:" + result);
msg = msg + result;
} else if (typeof(result) == "object") {
if (result instanceof ArrayBuffer) {
console.log("received arraybuffer from html5, length is:" + result.byteLength);
msg = msg + "lenght is " + result.byteLength;
} else {
console.log("not support");
}
} else {
console.log("not support");
}
output.innerHTML = msg;
}
}
}
})

// 3. 使用h5Port往ets侧发送消息.
function PostMsgToEts(data) {
if (h5Port) {
h5Port.postMessage(data);
} else {
console.error("h5Port is null, Please initialize first");
}
}

# 总结

  1. 在原生通过 this.controller.createWebMessagePorts(); 创建两个端口,port1 用于原生,port0 用于 h5 侧。
  2. h5 侧识别是否是初始化 port,并保存
  3. 基于 port0 和 port1 进行通信

# JavaScriptProxy 注册 JS 对象在 h5 的 window 对象中

# 鸿蒙应用原生侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// xxx.ets
import web_webview from '@ohos.web.webview'

@Entry
@Component
struct Index {
controller: web_webview.WebviewController = new web_webview.WebviewController();
testObj = {
test: (data) => {
return "ArkUI Web Component";
},
toString: () => {
console.log('Web Component toString');
}
}

build() {
Column() {
Button('refresh')
.onClick(() => {
try {
this.controller.refresh();
} catch (error) {
console.error(`Errorcode: ${error.code}, Message: ${error.message}`);
}
})
Button('Register JavaScript To Window')
.onClick(() => {
try {
this.controller.registerJavaScriptProxy(this.testObj, "objName", ["test", "toString"]);
} catch (error) {
console.error(`Errorcode: ${error.code}, Message: ${error.message}`);
}
})
Web({ src: $rawfile('index.html'), controller: this.controller })
.javaScriptAccess(true)
}
}
}

# h5 侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
<button type="button" onclick="htmlTest()">Click Me!</button>
<p id="demo"></p>
</body>
<script type="text/javascript">
function htmlTest() {
let str=objName.test();
document.getElementById("demo").innerHTML=str;
console.log('objName.test result:'+ str)
}
</script>
</html>

# runJavaScript 调用 h5 侧方法

# 鸿蒙应用原生侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import web_webview from '@ohos.web.webview'

@Entry
@Component
struct WebComponent {
controller: web_webview.WebviewController = new web_webview.WebviewController();
@State webResult: string = ''

build() {
Column() {
Text(this.webResult).fontSize(20)
Web({ src: $rawfile('index.html'), controller: this.controller })
.javaScriptAccess(true)
.onPageEnd(e => {
try {
this.controller.runJavaScript(
'test()',
(error, result) => {
if (error) {
console.info(`run JavaScript error: ` + JSON.stringify(error))
return;
}
if (result) {
this.webResult = result
console.info(`The test() return value is: ${result}`)
}
});
console.info('url: ', e.url);
} catch (error) {
console.error(`ErrorCode: ${error.code}, Message: ${error.message}`);
}
})
}
}
}

# h5 侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body>
Hello world!
</body>
<script type="text/javascript">
function test() {
console.log('Ark WebComponent')
return "This value is from index.html"
}
</script>
</html>