簡體   English   中英

Flutter WebView blob pdf 下載

[英]Flutter WebView blob pdf download

我正在嘗試使用flutter從網站下載文件,我首先使用了evaluateJavaScript並在單擊生成按鈕之前更改了一些值,該按鈕應該將適當的pdf文件下載到手機。

這是我的代碼:

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

這是控制台:
這是控制台

有人能幫我嗎?

使用 blob url 下載文件很棘手,並且在 Flutter 中的 webviews 的當前狀態下不支持開箱即用。 有3個流行的插件

社區存儲庫中的 README 中有一個注釋

我們正在與 Flutter 團隊密切合作,將所有社區插件功能集成到官方 WebView 插件中。 我們將盡最大努力解決 PR​​ 和錯誤修正,但我們現在的首要任務是合並我們的兩個代碼庫。 合並完成后,我們將棄用社區插件以支持官方插件

要構建完全有效且無錯誤的 webview,還有很多工作要做。 目前對於像這里提到的更具挑戰性的任務,最好的嘗試是使用flutter_inappwebview ,它非常流行並且被很多人成功使用。 存在與 blob 文件相關的問題 正如我們在您的代碼段中看到的,您已經使用了這個插件。 要下載 blob 文件,您可以嘗試將 blob:url 轉換為 base64,例如在這種情況下從 Android WebViewClient 內的網站下載 Blob 文件

可能的解決方法

向您的 webview ( _controller ) 添加JavaScriptHandler 我認為onWebViewCreated可能沒問題。

        controller.addJavaScriptHandler(
          handlerName: _webViewHandlerName,
          callback: (data) async {
            if (data.isNotEmpty) {
              final String receivedFileInBase64 = data[0];
              final String receivedMimeType = data[1];

              // NOTE: create a method that will handle your extensions
              final String yourExtension =
                  _mapMimeTypeToYourExtension(receivedMimeType); // 'pdf'

              _createFileFromBase64(
                  receivedFileInBase64, 'YourFileName', yourExtension);
            }
          },
        );

JavaScript 處理程序將接收存儲在數組中的兩個值。 第一個參數是以 base64 編碼的文件,第二個參數是 mimeType 例如application/pdf 擁有有關 mimeType 的信息允許我們獲取有關用於保存文件的擴展名的信息。 它們可以很容易地映射應用程序/pdf => 'pdf' 等。

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

最后,在可以處理 blob url 的地方調用 JavaScript。

       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 代碼中硬編碼更好)它打開 blob url 並傳遞給 encodingBase64 數據和 mimeType 作為我們在 dart 中的處理程序blobToBase64Handler參數。

var xhr = new XMLHttpRequest();
var blobUrl = "blobUrlPlaceholder";
console.log(blobUrl);
xhr.open('GET', blobUrl, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
  if (this.status == 200) {
    var blob = this.response;
    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = function() {
      var base64data = reader.result;
      var base64ContentArray = base64data.split(",")     ;
      var mimeType = base64ContentArray[0].match(/[^:\s*]\w+\/[\w-+\d.]+(?=[;| ])/)[0];
      var decodedFile = base64ContentArray[1];
      console.log(mimeType);
      window.flutter_inappwebview.callHandler('blobToBase64Handler', decodedFile, mimeType);
    };
  };
};
xhr.send();

來源: 從 Android WebViewClient 內的網站下載 Blob 文件

來源:如何在 Flutter 中解碼 base64 PDF 字符串?

它不干凈,看起來很笨拙,但找不到更好更容易的了

我為 Android 和 iOS 編寫了一個解決方案。 它可以支持任何類型的文件。

  1. 使用 Fluter 和 Jaguar 或其他后端框架構建一個簡單的后端
  2. 將 blob 轉換為 formData 並將其發布到 Flutter。

完整代碼: https : //github.com/guoguoguilai/flutter-webview-blob-download

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM