HarmonyOS鸿蒙Next中FLutter混合开发使用Flutter_inappwebview是否支持设置Refere,如何添加

HarmonyOS鸿蒙Next中FLutter混合开发使用Flutter_inappwebview是否支持设置Refere,如何添加 【问题描述】:flutter_inappwebview加载html片段,html格式的片段包含oss上面的资源,现在我们做一下referer限制

【问题现象】:不涉及

【版本信息】:不涉及

【复现代码】:不涉及

【尝试解决方案】:不涉及

3 回复

开发者您好,请查看如下方案:

【解决方案】

您可以在header中设置Refere,参考如下案例:

// main.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview_platform_interface/flutter_inappwebview_platform_interface.dart';
import 'package:flutter_inappwebview_ohos/flutter_inappwebview_ohos.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  OhosInAppWebViewPlatform.registerWith();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Referer Header Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const RefererDemoPage(),
    );
  }
}

class RefererDemoPage extends StatefulWidget {
  const RefererDemoPage({super.key});

  @override
  State<RefererDemoPage> createState() => _RefererDemoPageState();
}

class _RefererDemoPageState extends State<RefererDemoPage> {
  PlatformInAppWebViewController? _controller;
  String _headerInfo = '等待加载...';
  final String _referer = 'https://my-custom-referer.com';

  /// httpbin.org/headers 会返回 JSON 格式的请求头信息,可用于验证 Referer
  static const String _testUrl = 'https://httpbin.org/headers';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Referer Header 验证')),
      body: Column(
        children: [
          _buildInfoCard(),
          Expanded(child: _buildWebView()),
          _buildActions(),
        ],
      ),
    );
  }

  Widget _buildInfoCard() {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(12),
      color: Colors.grey[100],
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            '设置的 Referer: $_referer',
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
          ),
          const SizedBox(height: 4),
          Text(
            '目标 URL: $_testUrl',
            style: const TextStyle(fontSize: 12, color: Colors.grey),
          ),
          const Divider(),
          const Text(
            '服务端收到的 Headers:',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
          ),
          const SizedBox(height: 4),
          Text(_headerInfo, style: const TextStyle(fontSize: 12)),
        ],
      ),
    );
  }

  Widget _buildWebView() {
    final platform = PlatformInAppWebViewWidget(
      PlatformInAppWebViewWidgetCreationParams(
        initialUrlRequest: URLRequest(
          url: WebUri(_testUrl),
          headers: {'Referer': _referer},
        ),
        initialSettings: InAppWebViewSettings(
          javaScriptEnabled: true,
        ),
        onWebViewCreated: (controller) {
          _controller = controller;
        },
        onLoadStop: (controller, url) async {
          _extractHeaders(controller);
        },
      ),
    );
    return platform.build(context);
  }

  Widget _buildActions() {
    return Padding(
      padding: const EdgeInsets.all(12),
      child: Row(
        children: [
          Expanded(
            child: ElevatedButton(
              onPressed: () => _loadWithReferer('https://another-referer.com'),
              child: const Text('换一个 Referer 加载'),
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: ElevatedButton(
              onPressed: () => _loadWithoutReferer(),
              child: const Text('不带 Referer 加载'),
            ),
          ),
        ],
      ),
    );
  }

  void _loadWithReferer(String referer) {
    _controller?.loadUrl(
      urlRequest: URLRequest(
        url: WebUri(_testUrl),
        headers: {'Referer': referer},
      ),
    );
    setState(() {
      _headerInfo = '正在加载 (Referer: $referer)...';
    });
  }

  void _loadWithoutReferer() {
    _controller?.loadUrl(
      urlRequest: URLRequest(url: WebUri(_testUrl)),
    );
    setState(() {
      _headerInfo = '正在加载 (无 Referer)...';
    });
  }

  Future<void> _extractHeaders(PlatformInAppWebViewController controller) async {
    try {
      final result = await controller.evaluateJavascript(
        source: 'document.body.innerText',
      );
      if (result != null) {
        final text = result is String ? result : result.toString();
        final decoded = json.decode(text);
        final headers = decoded['headers'] as Map<String, dynamic>?;
        if (headers != null) {
          final refererValue = headers['Referer'] ?? headers['referer'] ?? '未检测到';
          final buffer = StringBuffer();
          buffer.writeln('Referer: $refererValue');
          buffer.writeln('---');
          headers.forEach((key, value) {
            buffer.writeln('$key: $value');
          });
          setState(() => _headerInfo = buffer.toString());
          return;
        }
      }
      setState(() => _headerInfo = '解析响应失败,请查看 WebView 中的原始 JSON');
    } catch (e) {
      setState(() => _headerInfo = '解析异常: $e');
    }
  }
}
// pubsepc.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_inappwebview_platform_interface:
    path: "./flutter_inappwebview_platform_interface"
  flutter_inappwebview_ohos:
    path: "./flutter_inappwebview_ohos"

dependency_overrides:
  flutter_inappwebview_platform_interface:
    path: "./flutter_inappwebview_platform_interface"
  flutter_inappwebview_ohos:
    path: "./flutter_inappwebview_ohos"

更多关于HarmonyOS鸿蒙Next中FLutter混合开发使用Flutter_inappwebview是否支持设置Refere,如何添加的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在HarmonyOS Next中,Flutter混合开发使用flutter_inappwebview插件时,设置Referer可通过WebView的initialHeaders参数实现。具体操作是在创建WebView时,于headers中添加"Referer"字段并指定值。示例代码:initialHeaders: {“Referer”: “your_referer_url”}。该插件基于Web组件封装,支持自定义HTTP请求头。

在HarmonyOS Next中进行Flutter混合开发时,flutter_inappwebview插件本身并不直接提供设置Referer的API。不过,你可以通过以下两种方式在加载请求时添加Referer请求头:

方法一:使用 initialUrlRequestinitialFile 时设置

如果你是通过URL或本地文件初始化WebView,可以在创建请求时添加自定义请求头。

InAppWebView(
  initialUrlRequest: URLRequest(
    url: Uri.parse('https://your-oss-domain.com/path/to/resource'),
    headers: {
      'Referer': 'https://your-allowed-domain.com' // 设置Referer
    },
  ),
)

方法二:通过 shouldOverrideUrlLoading 拦截请求并添加

对于页面内后续发起的请求(如加载OSS资源),可以通过 shouldOverrideUrlLoading 回调拦截,并为特定域名的请求添加Referer。

InAppWebView(
  initialUrlRequest: URLRequest(url: Uri.parse('your_initial_url')),
  shouldOverrideUrlLoading: (controller, navigationAction) async {
    final url = navigationAction.request.url.toString();
    
    // 判断是否为OSS资源请求
    if (url.startsWith('https://your-oss-domain.com')) {
      // 创建带Referer的新请求
      final newRequest = URLRequest(
        url: navigationAction.request.url,
        headers: {
          ...navigationAction.request.headers ?? {},
          'Referer': 'https://your-allowed-domain.com'
        },
      );
      
      // 加载新请求
      controller.loadUrl(urlRequest: newRequest);
      return NavigationActionPolicy.CANCEL; // 取消原请求
    }
    
    return NavigationActionPolicy.ALLOW; // 允许其他请求
  },
)

注意事项

  1. 插件兼容性:确保使用的 flutter_inappwebview 版本与HarmonyOS Next的Flutter环境兼容。
  2. 请求头限制:部分请求头(如 Referer)可能受底层Web引擎(如系统WebView)限制,需测试确认是否生效。
  3. 资源加载:如果HTML片段通过 loadData() 加载,其中的OSS资源请求可能无法通过上述方式拦截,建议改用 initialUrlRequestinitialFile 方式加载内容。

以上方法可实现在HarmonyOS Next的Flutter混合开发中为 flutter_inappwebview 的请求添加Referer。

回到顶部