欢迎光临
我们一直在努力

uniapp webview和小程序的消息通信

实现在webview即H5 中生成复杂海报图,H5生成海报内容可以更丰富且简单 因为可以截图

生成图片在webview上传到oss 把oss的地址回传给小程序 小程序下载或者直接把图片base64回传

两部分脚本示例 

1 vue

<template>
<view class="container p-4 flex flex-col items-center">
<u-text text="小程序 – H5 通信示例" type="primary" size="24" bold class="mb-4"></u-text>

<u-button type="success" @click="openWebView" class="mb-6 w-full">
{{ showWebView ? '关闭 WebView' : '打开 WebView 开始通信' }}
</u-button>

<u-alert
v-if="lastMessage"
title="接收到 H5 消息"
:description="lastMessage"
type="info"
:closable="true"
></u-alert>

<view v-if="showWebView" class="webview-wrapper">
<web-view
:src="webViewUrl"
@message="handleWebViewMessage"
@load="handleWebViewLoad"
class="poster-webview"
>
</web-view>
</view>
</view>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// ——————- 响应式数据 ——————-
const showWebView = ref<boolean>(false)
const lastMessage = ref<string>('')

// 请将此 URL 替换为您本地 H5 服务的 IP 地址和端口
const webViewUrl = ref<string>('https://www.demo.com/')
// 💡 小程序调试时,请确保使用 http://your-local-ip:port/index.html 并开启不校验域名

// ——————- 方法 ——————-

/**
* 打开或关闭 web-view
*/
const openWebView = () => {
if (showWebView.value) {
showWebView.value = false
uni.showToast({ title: 'WebView 已关闭', icon: 'none' })
} else {
showWebView.value = true
uni.showToast({ title: 'WebView 已打开', icon: 'none' })
}
}

/**
* 小程序环境:处理web-view加载完成
*/
const handleWebViewLoad = () => {
console.log('WebView加载完成')
// 可以在这里向 H5 页面发送一条初始化消息
// uni.postWebViewMessage({ data: { action: 'INIT' } });
}

/**
* 小程序环境:处理web-view发送的消息
*/
const handleWebViewMessage = (event: { detail: { data: any[] } }) => {
// web-view 的 data 是一个数组,即使只发送一个对象,也会被包装在数组中
const messageData = event.detail.data[0]

console.log('✅ 接收到 H5 页面消息:', messageData)

if (messageData && messageData.action === 'H5_POST_SUCCESS') {
lastMessage.value = `H5 页面发送成功!内容: ${messageData.payload}`

// 演示:接收到消息后可以关闭 web-view
setTimeout(() => {
showWebView.value = false
}, 1000)

uni.showToast({ title: '已接收 H5 消息并关闭 WebView', icon: 'success' })
}
}
</script>

<style scoped>
.webview-wrapper {
/* 必须给 web-view 容器一个明确的高度 */
width: 100%;
height: 60vh; /* 确保高度可见 */
border: 1px solid #ddd;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.poster-webview {
width: 100%;
height: 100%;
}
</style>

2 index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>H5 消息发送页面</title>
    
    <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> 

    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            background-color: #f7f7f7;
            text-align: center;
        }
        .container {
            padding: 20px;
            border: 2px dashed #007aff;
            background-color: white;
            border-radius: 8px;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #007aff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 20px;
        }
        .status {
            margin-top: 15px;
            font-weight: bold;
            color: #333;
        }
    </style>
</head>
<body>

    <div class="container">
        <h1>H5 页面 (内嵌在 web-view 中)</h1>
        <p>点击按钮,将消息发送给小程序宿主页面。</p>
        
        <button οnclick="sendMessage()">发送消息给小程序</button>
        
        <div class="status" id="status">等待发送…</div>
    </div>

    <script>
        const statusElement = document.getElementById('status');

        function sendMessage() {
            const messagePayload = {
                action: 'H5_POST_SUCCESS',
                payload: '这是来自 H5 页面的测试消息 ' + new Date().toLocaleTimeString()
            };
        
            if (window.wx && window.wx.miniProgram && window.wx.miniProgram.postMessage) {
                
                // 1. 发送消息
                window.wx.miniProgram.postMessage({
                    data: messagePayload
                });
                
                statusElement.textContent = '✅ 消息发送成功,尝试关闭 web-view…';
                
                // 2. 关键操作:发送消息后,立即触发小程序页面的返回(关闭 web-view)
                // 确保 jweixin-1.3.2.js 已经引入
                if (window.wx.miniProgram.navigateBack) {
                    window.wx.miniProgram.navigateBack({
                        delta: 1 // 返回层级,通常是 1
                    });
                } else {
                    statusElement.textContent += ' ❌ 错误:navigateBack 方法不存在。';
                }
        
            } else {
                statusElement.textContent = '❌ 错误:window.wx.miniProgram.postMessage 不存在。';
            }
        }
        
        window.onload = () => {
             statusElement.textContent = 'H5 页面加载完成。';
        }
    </script>
</body>
</html>

注意事项

微信小程序 web-view 的限制

接收 postMessage 消息的时机: 微信小程序为了优化性能和避免通信阻塞,设置了只有在 web-view 销毁、关闭或跳转到非业务域名页面时,才会将之前累积的 postMessage 消息批量发送给小程序宿主页面。

当用户在 H5 页面点击发送按钮时:

  • H5 页面执行 postMessage 发送消息。

  • H5 页面立即执行 wx.miniProgram.navigateBack()。

  • 小程序 web-view 被关闭/销毁。

  • 微信系统将 postMessage 累积的消息立即发送给小程序。

  • 小程序页面的 @message 事件被触发,接收到消息。

  • 小程序执行接收逻辑,通知用户成功,流程完成。

  • v2 在同一页面打开webview 发送消息后关闭webview 继续保持在打开页面 不回退

    1 vue

    <template>
    <view class="container p-4 flex flex-col items-center">
    <u-text
    text="小程序 – H5 交互示例 (v-if 控制)"
    type="primary"
    size="24"
    bold
    class="mb-4"
    ></u-text>

    <u-button
    :type="showWebView ? 'error' : 'success'"
    @click="toggleWebView"
    class="mb-6 w-full"
    >
    {{ showWebView ? '正在显示 WebView,点击可强制隐藏' : '打开 WebView' }}
    </u-button>

    <u-alert
    v-if="lastMessage"
    title="接收到 H5 消息,WebView 已关闭"
    :description="lastMessage"
    type="info"
    :closable="true"
    ></u-alert>

    <view v-if="showWebView" class="webview-wrapper">
    <web-view
    :src="webViewUrl"
    @message="handleWebViewMessage"
    @load="handleWebViewLoad"
    class="poster-webview"
    >
    </web-view>
    </view>
    </view>
    </template>

    <script setup lang="ts">
    import { ref } from 'vue'
    import { onLoad } from '@dcloudio/uni-app'

    // ——————- 响应式数据 ——————-
    const showWebView = ref<boolean>(false)
    const lastMessage = ref<string>('')

    // 替换为您实际的 HTTPS 域名,或者本地 IP 地址(调试时)
    const BASE_URL = 'https://www.demo.com'
    const webViewUrl = ref<string>('')

    // ——————- 方法 ——————-

    /**
    * 切换 web-view 状态
    */
    const toggleWebView = () => {
    if (showWebView.value) {
    showWebView.value = false
    uni.showToast({ title: 'WebView 已隐藏', icon: 'none' })
    } else {
    // 关键:添加时间戳参数,确保每次加载都是最新的,避免缓存
    webViewUrl.value = `${BASE_URL}?t=${Date.now()}`
    showWebView.value = true
    uni.showToast({ title: 'WebView 已打开', icon: 'none' })
    }
    }

    /**
    * 小程序环境:处理 web-view 加载完成
    */
    const handleWebViewLoad = () => {
    console.log('WebView加载完成,可以等待 H5 页面发送消息')
    }

    /**
    * 小程序环境:处理 web-view 发送的消息
    */
    const handleWebViewMessage = (event: { detail: { data: any[] } }) => {
    // web-view 的 data 结构是一个数组,即使只发送一个对象
    const messageData = event.detail.data[0]

    console.log('✅ 接收到 H5 页面消息:', messageData)

    if (messageData && messageData.action === 'H5_POST_SUCCESS') {
    // 1. 接收消息内容
    lastMessage.value = `H5 页面发送成功!内容: ${messageData.payload}`

    // 2. 关键操作:接收到消息后,立即通过 v-if 隐藏组件
    // H5 页面发送消息后执行了 reload,这已经触发了消息发送。
    // 小程序接收到消息后,隐藏组件,完成了流程。
    showWebView.value = false

    uni.showToast({ title: '消息接收成功,WebView 已隐藏', icon: 'success' })
    }
    }
    </script>

    <style scoped>
    .webview-wrapper {
    /* 必须给 web-view 容器一个明确的高度 */
    width: 100%;
    height: 60vh;
    border: 1px solid #ddd;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }

    .poster-webview {
    width: 100%;
    height: 100%;
    }
    </style>

    index.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>H5 消息发送页面</title>
        
        <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script> 

        <style>
            body {
                font-family: Arial, sans-serif;
                padding: 20px;
                background-color: #fff;
                text-align: center;
            }
            .container {
                padding: 20px;
                border: 2px dashed #ff5733;
                background-color: #fce4e4;
                border-radius: 8px;
            }
            button {
                padding: 10px 20px;
                font-size: 16px;
                background-color: #ff5733;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                margin-top: 20px;
            }
            .status {
                margin-top: 15px;
                font-weight: bold;
                color: #333;
            }
        </style>
    </head>
    <body>

        <div class="container">
            <h1>H5 页面</h1>
            <p>发送消息后,本页面将刷新,小程序将隐藏 web-view 组件。</p>
            
            <button οnclick="sendMessage()">发送消息并强制关闭 WebView</button>
            
            <div class="status" id="status">等待发送…</div>
        </div>

        <script>
            const statusElement = document.getElementById('status');

            function sendMessage() {
                const messagePayload = {
                    action: 'H5_POST_SUCCESS',
                    // 这里可以替换为您的 Base64 海报数据
                    payload: '这是来自 H5 的成功消息 ' + new Date().toLocaleTimeString() 
                };
                
                const HOST_PAGE_PATH = '/pages/major/major';

                if (window.wx && window.wx.miniProgram && window.wx.miniProgram.postMessage) {
                    
                    // 1. 发送消息
                    window.wx.miniProgram.postMessage({
                        data: messagePayload
                    });
                    
                    statusElement.textContent = '✅ 消息已发送,正在触发强制刷新…';
                    
                    // 2. 关键操作:使用 reLaunch 强制重载宿主页
                    if (window.wx.miniProgram.reLaunch) {
                        window.wx.miniProgram.reLaunch({
                            url: HOST_PAGE_PATH,
                            success: () => {
                                 // reLaunch 成功后 H5 页面会被销毁
                            },
                            fail: (err) => {
                                 statusElement.textContent = 'reLaunch 失败,可能路径错误或不在小程序环境。';
                                 console.error('reLaunch 失败:', err);
                            }
                        });
                    } else {
                        // 兼容旧版,但会触发回退
                        window.wx.miniProgram.navigateBack({ delta: 1 });
                    }

                } else {
                    statusElement.textContent = '❌ 错误:通信 API 未找到。';
                    console.error('通信 API 未找到,请确保在小程序 web-view 中打开,并引入了 JSSDK。');
                }
            }
            
            window.onload = () => {
                 statusElement.textContent = 'H5 页面加载完成。';
            }
        </script>
    </body>
    </html>

    赞(0)
    未经允许不得转载:171主机测评 » uniapp webview和小程序的消息通信
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址