跳到主要内容

flutter获取js渲染后的html内容,拦截媒体文件

管

管理员

flutter

2024年08月19日 1,977 次阅读
本页目录
使用webview_flutter创建一个WebView
等待页面加载完成
注入JavaScript来获取渲染后的HTML内容
使用JavaScript拦截网络请求,识别并下载mp3、mp4等文件
 
dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.0.0
  path_provider: ^2.0.11
 
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:path_provider/path_provider.dart';

class WebContentExtractor extends StatefulWidget {
  final String url;

  const WebContentExtractor({Key? key, required this.url}) : super(key: key);

  @override
  _WebContentExtractorState createState() => _WebContentExtractorState();
}

class _WebContentExtractorState extends State<WebContentExtractor> {
  late WebViewController _controller;
  String? _htmlContent;
  List<String> _downloadedFiles = [];

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageFinished: (String url) {
            _extractContent();
          },
        ),
      )
      ..loadRequest(Uri.parse(widget.url));
  }

  Future<void> _extractContent() async {
    // 获取渲染后的HTML内容
    _htmlContent = await _controller.runJavaScriptReturningResult(
      "document.documentElement.outerHTML;"
    ) as String?;

    // 注入JavaScript以拦截网络请求
    await _controller.runJavaScript('''
      (function() {
        var originalFetch = window.fetch;
        window.fetch = function() {
          return originalFetch.apply(this, arguments).then(function(response) {
            var url = response.url;
            if (url.endsWith('.mp3') || url.endsWith('.mp4')) {
              window.flutter_inappwebview.callHandler('onResourceDetected', url);
            }
            return response;
          });
        };
      })();
    ''');

    // 添加JavaScript处理程序
    await _controller.addJavaScriptChannel(
      'flutter_inappwebview',
      onMessageReceived: (JavaScriptMessage message) {
        _downloadFile(message.message);
      },
    );

    setState(() {});
  }

  Future<void> _downloadFile(String url) async {
    try {
      final response = await HttpClient().getUrl(Uri.parse(url));
      final httpResponse = await response.close();
      final bytes = await consolidateHttpClientResponseBytes(httpResponse);
      final dir = await getApplicationDocumentsDirectory();
      final file = File('${dir.path}/${url.split('/').last}');
      await file.writeAsBytes(bytes);
      setState(() {
        _downloadedFiles.add(file.path);
      });
    } catch (e) {
      print('Error downloading file: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Web Content Extractor')),
      body: Column(
        children: [
          Expanded(
            child: WebViewWidget(controller: _controller),
          ),
          if (_htmlContent != null)
            Text('HTML content extracted (length: ${_htmlContent!.length})'),
          if (_downloadedFiles.isNotEmpty)
            Text('Downloaded files: ${_downloadedFiles.join(", ")}'),
        ],
      ),
    );
  }
}
WebContentExtractor(url: 'https://example.com')

Related

相关文章

同分类文章 →
2026年10月31日 flutter

`auth()->id()` 到底返回谁?Sanctum 多态令牌与双会员系统的踩坑记录

## 引子先看一段看起来很正常的代码:```php$userId = auth('sanctum')-&gt;id();if ($userId) {    $res['isLiked'] = $this-&gt;likes()        -&gt;where('user_id', $userId

2026年07月28日 flutter

Dart 3 记录(Records)和密封类(Sealed classes)

Dart 3 引入了几个极其强大的语言特性,其中最耀眼、对我们日常开发改变最大的就是 记录(Records) 和 密封类(Sealed classes),它们配合 模式匹配(Pattern Matching),让 Dart 的表现力达到了现代编程语言(如 Swift、Kotlin、Rust

2026年06月29日 flutter

flutter的 Clean Architecture架构设计

Clean Architecture(清晰架构)是一种将应用程序分层的设计模式,强调关注点分离与依赖规则,通过将业务逻辑与框架、UI、数据源解耦,提升代码的可测试性、可维护性与可扩展性。在 Flutter/Dart 环境下,Clean Architecture 通

WeChat

扫码加我微信

微信二维码