Flutter WebView Blob pdf下载 [英] Flutter WebView blob pdf download

查看:231
本文介绍了Flutter WebView Blob pdf下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Flutter从网站下载文件,我首先使用了validateJavaScript,并更改了一些值,然后单击应该将适当的pdf文件下载到手机的生成按钮.

I am trying to download a file from a website using flutter, I first used evaluateJavaScript and changed some values before clicking a generate button wich is supposed to download an appropriate pdf file to the phone.

这是我的代码:

InAppWebView(
        initialUrl: '...',
        initialOptions: InAppWebViewGroupOptions(
          crossPlatform: InAppWebViewOptions(
              debuggingEnabled: true,
              useOnDownloadStart: true,
              javaScriptEnabled: true,
          ),
        ),
        //javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (InAppWebViewController webViewController) {
          _controller = webViewController;
          },
          onLoadStop: (_controller ,url) async {
          await _loadData();

          _controller.evaluateJavascript(source:
"console.log(document.getElementById('field-lastname').value = '${data[Field.name]}' );"
+"console.log(document.getElementById('generate-btn').click());"

           );
          },

          onDownloadStart:(_controller,url) async{
            print("onDownloadStart $url");
            final taskId = await FlutterDownloader.enqueue(
                url: url,
                savedDir: (await getExternalStorageDirectory()).path,
            showNotification: true, // show download progress in status bar (for Android)
            openFileFromNotification: true,);
          },

      ),

打印的网址就是这样

onDownloadStart blob:https://example.com/a2a5316c-9290-4da7-8a2a-9f899861046a

这是控制台

有人可以帮助我吗?

推荐答案

在Flutter中,使用blob url下载文件非常棘手,并且不支持在开箱即用的状态下使用.有3种流行的插件

Downloading file with blob url is tricky and not supported out of the box in currently state of webviews in Flutter. There are 3 popular plugins

  • flutter_webview_plugin - (community)
  • Webview_flutter (official)
  • flutter_inappwebview

社区存储库中的自述文件中有一条注释

There is a note at README in community repository

我们正在与Flutter团队紧密合作,以整合所有官方WebView插件中的社区插件功能.我们会尝试我们尽力解决PR和Bugfix,但我们现在的首要任务是合并我们的两个代码库.合并完成后,我们将弃用支持官方的社区插件

We are working closely with the Flutter Team to integrate all the Community Plugin features in the Official WebView Plugin. We will try our best to resolve PRs and Bugfixes, but our priority right now is to merge our two code-bases. Once the merge is complete we will deprecate the Community Plugin in favor of the Official one

要建立完全有效且无错误的Webview,还有很多工作要做.当前,对于此处提到的更具挑战性的任务,最好的尝试是使用 flutter_inappwebview ,它非常流行,并且被很多成功的人使用.与Blob文件相关的问题.正如我们在您的片段中所见,您已经使用了此插件.要下载blob文件,您可以尝试将blob:url转换为base64,例如在这种情况下从Android WebViewClient中的网站下载Blob文件

There is a lot of work yet to build fully working and bugfree webview. Currently for more challenging tasks like this mentioned here, the best attempt is to use flutter_inappwebview which is very popular and used by a lot people with success. There is issue associated with blob files. As we can see in your snippet you already used this plugin. To download blob file you can try convert blob:url to base64 like in this case Download Blob file from Website inside Android WebViewClient

在您的Web视图( _controller )中,添加 JavaScriptHandler .我认为 onWebViewCreated 可能还可以.

To your webview (_controller) add JavaScriptHandler. I would assume onWebViewCreated might be ok.

        controller.addJavaScriptHandler(
          handlerName: "blobToBase64Handler",
          callback: (data) {
            String receivedEncodedValueFromJs = data[0];
            _createPdfFromBase64(receivedEncodedValueFromJs.substring(28, receivedEncodedValueFromJs.length), "SomeFileName");
          },
        );

base64中的编码值将从JavaScript传递,并且以"data:application/pdf; base64,"开头.要使用以下方法生成pdf,请使用子字符串删除这些字符.

Encoded value in base64 will be passed from JavaScript and it starts with "data:application/pdf;base64,". To generate pdf using methods below we remove these characters using substring.

  _createPdfFromBase64(String encodedPdf, String fileName) async {
    var bytes = base64Decode(encodedPdf.replaceAll('\n', ''));
    final output = await getExternalStorageDirectory();
    final file = File("${output.path}/${fileName}.pdf");
    await file.writeAsBytes(bytes.buffer.asUint8List());
    print("${output.path}/${fileName}.pdf");
    await OpenFile.open("${output.path}/${fileName}.pdf");
    setState(() {});
  }

最后可以在其中处理blob url的地方调用js

finally where blob url can be handled invoke js

       onDownloadStart: (controller, url) async {
        print("onDownloadStart $url");
        var jsContent = await rootBundle.loadString("assets/js/base64.js");
        await controller.evaluateJavascript(
            source: jsContent.replaceAll("blobUrlPlaceholder", url));
      },

javascript(作为资产base64.js加载,比在Dart代码中硬编码更好):

javascript (load as asset base64.js, better than hardcoded in dart code):

var xhr = new XMLHttpRequest();
var blobUrl = "blobUrlPlaceholder";
console.log(blobUrl);
xhr.open('GET', blobUrl, true);
xhr.setRequestHeader('Content-type', 'application/pdf');
xhr.responseType = 'blob';
xhr.onload = function(e) {
    if (this.status == 200) {
        var blobPdf = this.response;
        var reader = new FileReader();
        reader.readAsDataURL(blobPdf);
        reader.onloadend = function() {
            base64data = reader.result;
            console.log(base64data);
            window.flutter_inappwebview.callHandler('blobToBase64Handler', base64data);
        };
    };
};
xhr.send();

来源:从Android内的网站下载Blob文件WebViewClient

来源:如何在Flutter中解码base64 PDF字符串?

它不干净,看上去很笨拙,但找不到更好,更容易的东西

It's not clean and looks hacky but could not find better and easier

这篇关于Flutter WebView Blob pdf下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆