Integrate Flutter for OpenHarmony with the V3 architecture

更新时间:
复制 MD 格式

Use a WebView to embed Alibaba Cloud Captcha 2.0 in a Flutter for OpenHarmony app. This approach loads your existing HTML5 business page inside the app and bridges verification results back to Flutter through a JavaScript handler, so you avoid native dependency issues while keeping full access to rapid HTML5 Captcha updates.

How it works

All communication flows through three components:

  1. HTML5 client — Your business page runs Captcha 2.0 and, on success, passes the verification parameters to Flutter via window.flutter_inappwebview.callHandler.

  2. Flutter app — Loads the HTML5 page in an InAppWebView and registers a JavaScript handler (testInterface) to receive the parameters.

  3. Server — Receives the parameters from Flutter and calls VerifyIntelligentCaptcha to complete secondary authentication.

Prerequisites

Before you begin, make sure you have:

WebView requirements

For Captcha 2.0 to work inside a WebView, the following conditions must be met:

  • JavaScript enabledjavaScriptEnabled: true in InAppWebViewGroupOptions

  • Network access — The ohos.permission.INTERNET and ohos.permission.GET_NETWORK_INFO permissions declared in module.json5

  • Stable base URL — Load HTML content with a consistent base URL (for example, https://localhost) so that Captcha scripts resolve correctly

Step 1: Integrate Captcha 2.0 on the HTML5 client

Integrate the Captcha 2.0 client code in your HTML5 business page. For implementation details, see Integrate the client for web and H5 pages (V3 architecture).

Note

If your business uses the V2 architecture, see Integrate the client for web and H5 pages (V2 architecture).

In the success callback, forward the verification parameters to Flutter using the flutter_inappwebview JavaScript handler:

// success callback function
function success(captchaVerifyParam) {
    // Send the verification result to Flutter (using the communication method of flutter_inappwebview)
    if (window.flutter_inappwebview && window.flutter_inappwebview.callHandler) {
        window.flutter_inappwebview.callHandler('testInterface', captchaVerifyParam);
    }
}

The handler name testInterface must match the name registered in the Flutter app (see Step 3).

Step 2: Integrate Captcha 2.0 on the server

On your server, integrate the Captcha 2.0 SDK and call VerifyIntelligentCaptcha to perform secondary authentication on the parameters received from Flutter. For implementation details, see Server-side integration.

Step 3: Load the Captcha page in Flutter

1. Add the flutter_inappwebview dependency

In pubspec.yaml, add the WebView plugin that supports the HarmonyOS platform:

dependencies:
  flutter:
  sdk: flutter
  # Use the WebView plugin that supports the HarmonyOS platform
  flutter_inappwebview:
    git:
      url: https://gitcode.com/openharmony-sig/flutter_inappwebview
      path: "flutter_inappwebview"

2. Declare network permissions

In ohos/entry/src/main/module.json5, add the following permissions under requestPermissions:

{
  "module": {
    "name": "entry",
    "type": "entry",
    // Other configurations
    // ...
    "requestPermissions": [
      {"name": "ohos.permission.INTERNET"},
      {"name": "ohos.permission.GET_NETWORK_INFO"}
    ]
  }
}

3. Create the Captcha page

Create a Flutter widget that loads the HTML5 page in an InAppWebView and registers the testInterface handler to receive verification parameters:

import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter/services.dart';

class CaptchaPage extends StatefulWidget {
  const CaptchaPage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<CaptchaPage> createState() => _CaptchaPageState();
}

class _CaptchaPageState extends State<CaptchaPage> {
  InAppWebViewController? _controller;

  @override
  void initState() {
    super.initState();
  }

  // Handle the Captcha verification result
  void _handleCaptchaResult(dynamic captchaVerifyParam) {
    try {
      print('Received Captcha parameters: $captchaVerifyParam');

      // Check if the parameters are empty
      if (captchaVerifyParam == null) {
        throw Exception('Received empty verification parameters');
      }

      // Directly send the verification parameters to the server
      _sendToServer(captchaVerifyParam);

    } catch (e) {
      print('Failed to process Captcha parameters: $e');
      _showSnackBar('Failed to process verification parameters: $e', isError: true);
    }
  }

  // Send verification parameters to the server (example)
  Future<void> _sendToServer(dynamic captchaVerifyParam) async {
    try {
      // Call your server-side API for secondary authentication here
      print('Preparing to send to the server for verification: $captchaVerifyParam');

      // Simulate successful server-side verification
      _showSnackBar('Server-side verification successful', isError: false);
    } catch (e) {
      print('Server-side verification failed: $e');
      _showSnackBar('Server-side verification failed: $e', isError: true);
    }
  }

  void _showSnackBar(String message, {bool isError = false}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: isError ? Colors.red : Colors.green,
        duration: const Duration(seconds: 3),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: _buildWebViewContent(),
    );
  }

  // Build the WebView content
  Widget _buildWebViewContent() {
    return Stack(
      children: [
        InAppWebView(
          initialData: InAppWebViewInitialData(
            data: "",
          ),
          initialOptions: InAppWebViewGroupOptions(
            crossPlatform: InAppWebViewOptions(
              javaScriptEnabled: true,
              useShouldOverrideUrlLoading: true,
            ),
          ),
          onWebViewCreated: (InAppWebViewController controller) async {
            _controller = controller;

            // Add a JavaScript handler
            _controller!.addJavaScriptHandler(
              handlerName: 'testInterface',
              callback: (args) {
                if (args.isNotEmpty) {
                  _handleCaptchaResult(args[0]);
                }
              },
            );

            // Load the HTML content
            try {
              String htmlContent = await rootBundle.loadString('assets/captcha.html');
              await _controller!.loadData(data: htmlContent, baseUrl: WebUri('https://localhost'));
            } catch (e) {
              print('Failed to load HTML: $e');
              _showSnackBar('Failed to load Captcha page: $e', isError: true);
            }
          },
        ),
      ],
    );
  }
}

4. Register the Captcha page in main.dart

import 'package:flutter/material.dart';
import 'captcha_page.dart';  // Import the Captcha page

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Alibaba Cloud Captcha Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CaptchaPage(title: 'Alibaba Cloud Captcha Demo'),
    );
  }
}

5. Declare the HTML asset

In pubspec.yaml, register the HTML file as an asset:

flutter:
  assets:
    - assets/index.html

6. Build and run

Compile and run the project:

flutter build hap --debug

Verify the integration

After the app starts, trigger the Captcha challenge in your HTML5 page. A successful integration shows a green SnackBar with "Server-side verification successful" after you complete the challenge. If the SnackBar does not appear, check the console output for error messages from _handleCaptchaResult or _sendToServer.

Troubleshooting

Captcha does not load in the WebView

Check that javaScriptEnabled is set to true in InAppWebViewGroupOptions. Also confirm that both ohos.permission.INTERNET and ohos.permission.GET_NETWORK_INFO are declared in module.json5. Missing either permission prevents the WebView from reaching Captcha servers.

The JavaScript handler receives no data

Confirm that the handler name in the HTML5 success callback (window.flutter_inappwebview.callHandler('testInterface', ...)) exactly matches the name registered in addJavaScriptHandler (handlerName: 'testInterface'). A name mismatch will cause the parameters not to be received by the Flutter handler.

HTML file fails to load

Verify that the asset path in rootBundle.loadString('assets/captcha.html') matches the path declared in pubspec.yaml. After changing pubspec.yaml, run flutter pub get and rebuild.

Download the demo

Flutter for OpenHarmony integration demo