HarmonyOS鸿蒙Next中flutter webview 支付宝h5支付 alipays协议 302 错误页面显示空白

HarmonyOS鸿蒙Next中flutter webview 支付宝h5支付 alipays协议 302 错误页面显示空白 flutter webview 支付宝h5支付 alipays协议 302 错误页面显示空白

==request.url onWebResourceError: ERR_UNKNOWN_URL_SCHEME, -302, alipays://platformapi/startApp

8 回复

楼主可以参考一下flutter这个拉起的代码:总体处理思路就是在WebView里面识别协议进行拦截,在原生里面也是这个思路

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher.dart';

// ... 在你的 State 类中

late final WebViewController _controller;

@Override
void initState() {
  super.initState();
  
  _controller = WebViewController()
    ..setJavaScriptMode(JavaScriptMode.unrestricted)
    ..setNavigationDelegate(
      NavigationDelegate(
        // 关键逻辑在这里
        onNavigationRequest: (NavigationRequest request) async {
          String url = request.url;

          // 1. 检测是否是支付宝的协议
          if (url.startsWith("alipays://") || url.startsWith("alipayhk://")) {
            Uri uri = Uri.parse(url);
            
            // 2. 尝试唤起支付宝 App
            try {
              if (await canLaunchUrl(uri)) {
                await launchUrl(uri, mode: LaunchMode.externalApplication);
              } else {
                // 可选:提示用户未安装支付宝,或不做处理让它停留在H5页面
                print("未安装支付宝或无法处理该 Scheme");
              }
            } catch (e) {
              print("唤起支付失败: $e");
            }

            // 3. 拦截请求,不让 WebView 继续加载这个链接,防止白屏/报错
            return NavigationDecision.prevent;
          }

          // 处理微信支付同理 (weixin://)
          if (url.startsWith("weixin://")) {
             Uri uri = Uri.parse(url);
             if (await canLaunchUrl(uri)) {
                await launchUrl(uri, mode: LaunchMode.externalApplication);
             }
             return NavigationDecision.prevent;
          }

          return NavigationDecision.navigate;
        },
        onWebResourceError: (WebResourceError error) {
          // 这里可以过滤掉那个 -302 错误,避免日志刷屏
          if (error.errorCode != -302 && error.description != "net::ERR_UNKNOWN_URL_SCHEME") {
             print("WebView error: ${error.description}");
          }
        },
      ),
    )
    ..loadRequest(Uri.parse('YOUR_PAYMENT_URL'));
}

更多关于HarmonyOS鸿蒙Next中flutter webview 支付宝h5支付 alipays协议 302 错误页面显示空白的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


同样问题

同问

部分H5的URL链接,会实现deeplink跳转拉端的逻辑,如果未实现拉端相关的代码会报ERR_UNKNOWN_URL_SCHEME的错误。

建议拦截flutter webview 请求, 判断是 alipays协议,就跳转到浏览器或者使用openLink跳转

参考ArkWeb的拦截跳转:

Web({ src: '', controller: this.controller })
  .javaScriptAccess(true)
  .domStorageAccess(true)
  .onLoadIntercept((event) => {
    // 返回true表示阻止此次加载,否则允许此次加载
    if (event && event.data.isRequestGesture()) {
      const url = event.data.getRequestUrl()
      if (url.startsWith('alipays://')) {
        const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
        context?.openLink(url)
        return true
      }
    }
    return false
  })

你好,我是用的flutter,这是原生代码吧,flutter_webview 如何实现?,

在HarmonyOS Next中,Flutter WebView遇到支付宝H5支付alipays协议返回302状态码导致页面空白,通常是因为WebView未正确处理支付协议的重定向。鸿蒙Next的WebView组件需要配置支持alipays等自定义URL Scheme。可通过在WebView的onLoadProgress事件中监听URL变化,使用鸿蒙的ArkTS/ETS接口拦截alipays协议,并调用系统能力启动支付宝客户端完成支付流程。

这是一个典型的由自定义协议(alipays://)在WebView中无法被正确处理导致的302重定向问题。错误码 ERR_UNKNOWN_URL_SCHEME 明确指出了这一点。

问题核心: 当Flutter WebView加载的H5页面尝试通过 alipays:// 协议调起支付宝客户端时,WebView默认无法识别此类非HTTP(S)的自定义URL Scheme,因此将其判定为错误,导致重定向中断,页面显示空白。

解决方案: 关键在于拦截WebView的页面加载请求,对特定的URL Scheme(如alipays://)进行自定义处理,通常是通过系统能力尝试调起对应的外部应用。

在HarmonyOS Next的Flutter开发环境中,你需要使用 webview_flutter 插件并实现 NavigationDelegate 来拦截和处理这类请求。

以下是核心代码示例:

import 'package:webview_flutter/webview_flutter.dart';

// 在构建WebView时,配置navigationDelegate
WebView(
  initialUrl: '你的支付页面URL',
  navigationDelegate: (NavigationRequest request) {
    // 判断是否为支付宝协议
    if (request.url.startsWith('alipays://') || 
        request.url.startsWith('alipay://')) {
      // 尝试使用url_launcher等插件调起支付宝
      // 例如:launchUrl(Uri.parse(request.url));
      // 或者使用HarmonyOS的系统能力调起应用
      
      // 阻止WebView继续加载此URL
      return NavigationDecision.prevent;
    }
    // 允许其他正常URL(http/https)继续加载
    return NavigationDecision.navigate;
  },
  onWebResourceError: (WebResourceError error) {
    // 可以在此处捕获错误,但主要逻辑应在navigationDelegate中处理
    print('Web资源错误: ${error.description}');
  },
)

关键步骤:

  1. 实现拦截:navigationDelegate 回调中检查所有请求的URL。
  2. 协议识别: 当URL以 alipays://alipay:// 开头时,识别为支付宝支付请求。
  3. 外部调起: 使用 url_launcher 插件的 launchUrl 方法,或直接调用HarmonyOS的系统URI接口(通过FFI或平台通道),尝试在设备上启动支付宝客户端。确保在应用的配置文件中声明了对该URL Scheme的查询权限。
  4. 阻止加载: 返回 NavigationDecision.prevent 以阻止WebView加载这个无法识别的协议URL,防止出现 ERR_UNKNOWN_URL_SCHEME 错误。
  5. 错误处理: 考虑调起支付宝失败的情况(例如用户未安装支付宝),应提供友好的用户提示,并可能引导用户回到支付页面或进行其他操作。

注意事项:

  • 权限与配置: 确保你的HarmonyOS应用在 module.json5 配置文件中声明了必要的权限,例如 ohos.permission.START_ABILITIES_EXTERNALLY(如果需要外部启动能力)以及对目标应用包名的查询权限。
  • 备用方案: 对于支付场景,建议与后端协商,提供备用的支付完成回调URL或支付状态查询机制,以防客户端调起支付过程中出现异常。

通过以上方式,你可以有效拦截支付宝的URL Scheme,并通过系统调起支付流程,从而避免302错误导致的空白页面。

回到顶部