问题描述
我正在尝试使用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
要建立完全有效且无错误的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下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!