龙空技术网

Flutter WebView 内容拦截器 ーー AppWebView 6

猫哥ducafecat 178

前言:

现时我们对“ios拦截webview的url拦截”可能比较关怀,咱们都需要了解一些“ios拦截webview的url拦截”的相关知识。那么小编也在网摘上汇集了一些对于“ios拦截webview的url拦截””的相关内容,希望姐妹们能喜欢,看官们一起来了解一下吧!

Flutter WebView 内容拦截器 ーー AppWebView 6

原文

前言

在本文中,我们将了解如何使用 flutter_inappwebview 插件为我们的 WebView 实例创建自定义 Content Block。

内容拦截器通常用于拦截广告,但你也可以拦截任何其他内容。拦截行为包括隐藏元素、拦截负载,以及在 iOS 和 macOS 上从 WebView 请求中剥离 cookie。

请记住,一般来说,Content Blockers 不能实现与 AdBlock 或 AdBlock Plus 等专用 extension 相同级别的功能。Content Blockers 是一组规则,当 WebView 找到需要阻止的内容时,它将永远不会从 WebView 获得任何回调或通知。

通过 InAppWebViewSettings 类的 contentBlockers 属性,我们可以定义 WebView 将使用的 ContentBlockers 实例的列表。

正文ContentBlocker 内容过滤类

ContentBlock 类是我们定义内容拦截行为的类。每个属性包含一个操作属性和一个触发器属性。该操作告诉 WebView 在遇到与触发器匹配的对象时要做什么。触发器告诉 WebView 何时执行相应的操作。

下面是一个基本的例子:

initialSettings: InAppWebViewSettings(contentBlockers: [  ContentBlocker(    trigger: ContentBlockerTrigger(      urlFilter: ".*",      resourceType: [        ContentBlockerTriggerResourceType.IMAGE,        ContentBlockerTriggerResourceType.STYLE_SHEET      ]    ),    action: ContentBlockerAction(      type: ContentBlockerActionType.BLOCK    )  )]),

在这个例子中,我们说的是为每个 URL 阻止每个图像和样式表的加载。

将 triggers 触发器添加到 Content Blocker 内容阻止器

触发器必须定义所需的 urlFilter 属性,该属性将正则表达式指定为与 URL 匹配的字符串。其他属性是可选的,可以修改触发器的行为。例如,可以将触发器限制为特定域,或者在 WebView 找到与特定域匹配的触发器时不应用触发器。

下面是一个内容拦截器的例子,它带有一个针对图像和样式表资源的触发器,WebView 可以在任何域中找到这些资源,但是指定的域除外:

initialSettings: InAppWebViewSettings(contentBlockers: [  ContentBlocker(    trigger: ContentBlockerTrigger(      urlFilter: ".*",      resourceType: [        ContentBlockerTriggerResourceType.IMAGE,        ContentBlockerTriggerResourceType.STYLE_SHEET      ],      unlessDomain: ["example.com", "github.com", "pub.dev"]    ),    action: ContentBlockerAction(      type: ContentBlockerActionType.BLOCK    )  )]),

对于更深层次的触发器自定义,您可以使用 ContentBlockerTrigger 的其他属性:

如果 URL 匹配应该区分大小写。默认情况下,它是不区分大小写的。Resource ceType: “ ContentBlockerTriggerResourceType”的列表,表示规则应该匹配的资源类型(浏览器打算如何使用资源)。如果未指定,则该规则匹配所有资源类型。IfDomain: 与 URL 域匹配的字符串列表; 将操作限制为特定域的列表。值必须是小写的 ASCII,或非 ASCII 的小写字母代码。在前面添加 * 以匹配域和子域。它不能和“ unless Domain”一起使用。Unless 域名: 与 URL 域名匹配的字符串列表; 在提供列表中的域名以外的任何站点上执行操作。值必须是小写的 ASCII,或非 ASCII 的小写字母代码。在前面添加 * 以匹配域和子域。它不能与“ ifDomain”一起使用。LoadType: “ ContentBlockerTriggerLoadType”的列表,可以包括两个相互排斥的值之一。如果未指定,则该规则匹配所有加载类型。“ ContentBlockerTriggerLoadType.FIRST_PARTY”仅在资源与主页资源具有相同的方案、域和端口时触发。如果资源与主页资源来自不同的域,则“ ContentBlockerTriggerLoadType.THIRD_PARTY”触发器。IfTopUrl: 与整个主文档 URL 匹配的字符串列表; 将操作限制为 URL 模式的特定列表。值必须是小写的 ASCII,或非 ASCII 的小写字母代码。它不能和“ unless TopUrl”一起使用。Unless TopUrl: 与整个主文档 URL 匹配的字符串数组; 在所提供列表中的 URL 模式以外的任何站点上进行操作。值必须是小写的 ASCII,或非 ASCII 的小写字母代码。它不能与“ ifTopUrl”一起使用。LoadContext: 指定加载上下文的字符串数组。IfFrameUrl: 用于匹配 iframe URL 的正则表达式列表。

检查每个特定属性的代码文档,以了解哪个平台支持该特性。

向内容屏蔽器添加 actions 操作

当触发器与资源匹配时,WebView 计算所有触发器并按顺序执行操作。

将具有相似操作的规则组合在一起以提高性能。例如,首先指定阻止内容加载的规则,然后指定阻止 Cookie 的规则。

操作只有两个有效属性: type 和 selector。操作类型是必需的。 如果类型是 ContentBlockerActionType.CSS_DISPLAY_NONE,也需要一个选择器; 否则,选择器是可选的。

下面是一个简单的例子:

initialSettings: InAppWebViewSettings(contentBlockers: [  ContentBlocker(    trigger: ContentBlockerTrigger(      urlFilter: ".*",    ),    action: ContentBlockerAction(      type: ContentBlockerActionType.CSS_DISPLAY_NONE,      selector: '.notification, .media, #developer-story'    )  )]),

有效类型包括:

BLOCK: 停止加载资源。如果资源被缓存,缓存将被忽略。BLOCK_COOKIES: 在将 Cookie 发送到服务器之前,从头中剥离 Cookie。这只能阻止 Cookie,否则 WebView 的隐私政策是可以接受的。结合“ IGNORE_PREVIOUS_RULES”不会覆盖浏览器的隐私设置。CSS_DISPLAY_NONE: 基于 CSS 选择器隐藏页面元素。选择器字段包含选择器列表。任何匹配的元素都将其 display 属性设置为 none,这将隐藏它。MAKE_HTTPS: 将 URL 从 http 更改为 https。具有指定(非默认)端口的 URL 和使用其他协议的链接不受影响。IGNORE_PREVIOUS_RULES: 忽略以前触发的动作。

检查每个特定类型的代码文档,以了解哪个平台支持它。

创建一个简单的广告屏蔽器

让我们用我们学到的知识创建一个简单的广告拦截器。

import 'package:flutter/foundation.dart';import 'package:flutter/material.dart';import 'package:flutter_inappwebview/flutter_inappwebview.dart';Future main() async {  WidgetsFlutterBinding.ensureInitialized();  if (!kIsWeb &&      kDebugMode &&      defaultTargetPlatform == TargetPlatform.android) {    await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);  }  runApp(const MaterialApp(home: MyApp()));}class MyApp extends StatefulWidget {  const MyApp({Key? key}) : super(key: key);  @override  State<MyApp> createState() => _MyAppState();}class _MyAppState extends State<MyApp> {  final GlobalKey webViewKey = GlobalKey();  // list of Ad URL filters to be used to block ads loading.  final adUrlFilters = [    ".*.doubleclick.net/.*",    ".*.ads.pubmatic.com/.*",    ".*.googlesyndication.com/.*",    ".*.google-analytics.com/.*",    ".*.adservice.google.*/.*",    ".*.adbrite.com/.*",    ".*.exponential.com/.*",    ".*.quantserve.com/.*",    ".*.scorecardresearch.com/.*",    ".*.zedo.com/.*",    ".*.adsafeprotected.com/.*",    ".*.teads.tv/.*",    ".*.outbrain.com/.*"  ];  final List<ContentBlocker> contentBlockers = [];  var contentBlockerEnabled = true;  InAppWebViewController? webViewController;  @override  void initState() {    super.initState();    // for each Ad URL filter, add a Content Blocker to block its loading.    for (final adUrlFilter in adUrlFilters) {      contentBlockers.add(ContentBlocker(          trigger: ContentBlockerTrigger(            urlFilter: adUrlFilter,          ),          action: ContentBlockerAction(            type: ContentBlockerActionType.BLOCK,          )));    }    // apply the "display: none" style to some HTML elements    contentBlockers.add(ContentBlocker(        trigger: ContentBlockerTrigger(          urlFilter: ".*",        ),        action: ContentBlockerAction(            type: ContentBlockerActionType.CSS_DISPLAY_NONE,            selector: ".banner, .banners, .ads, .ad, .advert")));  }  @override  Widget build(BuildContext context) {    return Scaffold(        appBar: AppBar(          title: const Text("Ads Content Blocker"),          actions: [            TextButton(              onPressed: () async {                contentBlockerEnabled = !contentBlockerEnabled;                if (contentBlockerEnabled) {                  await webViewController?.setSettings(                      settings: InAppWebViewSettings(                          contentBlockers: contentBlockers));                } else {                  await webViewController?.setSettings(                      settings: InAppWebViewSettings(contentBlockers: []));                }                webViewController?.reload();                setState(() {});              },              style: TextButton.styleFrom(foregroundColor: Colors.white),              child: Text(contentBlockerEnabled ? 'Disable' : 'Enable'),            )          ],        ),        body: SafeArea(            child: Column(children: <Widget>[          Expanded(            child: Stack(              children: [                InAppWebView(                  key: webViewKey,                  initialUrlRequest:                      URLRequest(url: WebUri(';)),                  initialSettings:                      InAppWebViewSettings(contentBlockers: contentBlockers),                  onWebViewCreated: (controller) {                    webViewController = controller;                  },                ),              ],            ),          ),        ])));  }}

使用这些规则可以防止出现大量的广告,比如谷歌广告。

单击禁用/启用按钮禁用或启用广告屏蔽功能。

WebView 广告屏蔽器示例。

代码

结束语

如果本文对你有帮助,请转发让更多的朋友阅读。

也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。

祝你有一个美好的一天~

© 猫哥

标签: #ios拦截webview的url拦截