0

我在我的颤振应用程序中使用 webview_flutter 插件。当 url 更改时,如何添加 header 参数以及如何以及如何跟踪 url 更改?那是我的代码。我尝试在 navigationDelegate 中使用 loadurl,但它不起作用。我怎样才能做到这一点?请帮忙

String URL = 'https://...../login-app?authkey=${globals.authkey}&test=1';
  WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(),
body: WebView(
        // initialUrl: 'https://...../login-app?authkey=${globals.authkey}',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller.complete(webViewController);
          webViewController.loadUrl(URL,headers: {"SB-app": "iphone"},);
        },
        navigationDelegate: (NavigationRequest request) async {
          print('allowing navigation to $request');
          if(request.url.contains('driver/chat') || request.url.contains('driver/on-map') || request.url.contains('driver/passanger-form') || request.url.contains('driver/login')) {
            _webViewController.loadUrl(request.url, headers: {"SB-app": "iphone"});
          }
          return NavigationDecision.navigate;
        },
        onPageStarted: (String url) async {
          print('Page started loading: $url');
        },
        onPageFinished: (String url) async {
          print('Page finished loading: $url');
        },
4

1 回答 1

1

您应该在事件声明中返回NavigationDecision.preventifnavigationDelegate防止当前导航并允许使用该标头值的新导航请求。但是,这在 iOS 上不起作用,因为使用该webview_plugin插件,NavigationRequest没有有关请求标头的信息,因此您将进入循环循环,因为您不知道对于该请求,您的标头是否有是否已经设置。

因此,对于您的用例,您可以使用我的flutter_inappwebview 插件使用shouldOverrideUrlLoading 事件(与 相同的navigationDelegate  事件webview_flutter),其中包含有关请求的更多信息,而不仅仅是 URL 字符串。为了能够监听此事件,您需要设置useShouldOverrideUrlLoading: trueWebView 选项。

这是一个使用https://github.com/flutter作为 URL的简单示例。尝试使用 Android 和 iOS 导航到 Flutter 主存储库、示例存储库或插件存储库:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  if (Platform.isAndroid) {
    await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
  }

  runApp(MaterialApp(home: new MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
    crossPlatform: InAppWebViewOptions(
      useShouldOverrideUrlLoading: true
    ),
    android: AndroidInAppWebViewOptions(
      useHybridComposition: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("InAppWebView Example")),
        body: SafeArea(
          child: Column(children: <Widget>[
            Expanded(
              child: Stack(
                children: [
                  InAppWebView(
                    initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")),
                    initialOptions: options,
                    shouldOverrideUrlLoading: (controller, navigationAction) async {
                      var request = navigationAction.request;
                      var url = request.url;
                      var isUrlMatching = url != null && (url.path.contains('flutter/flutter') || url.path.contains('flutter/samples') || url.path.contains('flutter/plugins'));

                      if(isUrlMatching) {

                        if (request.headers != null && request.headers!["SB-app"] != null) {
                          print('header already set! Allow the current navigation request');
                          return NavigationActionPolicy.ALLOW;
                        }
                        else {
                          if (request.headers == null) {
                            request.headers = {};
                          }
                          print('Header not found! Set the "SB-app" header');
                          request.headers!["SB-app"] = "iphone";
                          print('Make load request with "SB-app" header');
                          controller.loadUrl(urlRequest: request);

                          print('and cancel the current navigation request');
                          return NavigationActionPolicy.CANCEL;
                        }

                      }

                      // always allow all the other requests
                      return NavigationActionPolicy.ALLOW;
                    },
                  ),
                ],
              ),
            ),
        ])));
  }
}
于 2021-04-02T14:50:55.833 回答