Flutter中flutter_inappwebview上传文件代码报错求助
问题修复方案
1. endsWith 空安全报错
resource.url 可能为null,直接调用endsWith会触发空安全错误,需给所有判断添加空安全操作符:
if (resource.url?.endsWith('.css') == true || resource.url?.endsWith('.js') == true)
也可加入大小写兼容处理:
if (resource.url?.toLowerCase().endsWith('.css') ?? false || resource.url?.toLowerCase().endsWith('.js') ?? false)
2. addCrossOriginResourcePolicy 与 CrossOriginResourcePolicy 标红
该方法在新版 flutter_inappwebview 中已废弃,建议通过请求拦截器修改响应头实现跨源配置:
// 替换原有 onLoadResource,添加请求拦截逻辑 shouldInterceptRequest: (controller, request) async { final response = await controller.getUrlRequest(request: request); if (response != null && (request.url?.endsWith('.css') == true || request.url?.endsWith('.js') == true)) { return WebResourceResponse( data: response.data, mimeType: response.mimeType, encoding: response.encoding, statusCode: 200, reasonPhrase: 'OK', headers: {'Access-Control-Allow-Origin': '*', ...response.headers}, ); } return response; },
若使用旧版本包,需调整枚举名称为CrossOriginResourcePolicyValue,并使用对应方法:
await controller.setCrossOriginResourcePolicy(CrossOriginResourcePolicyValue.ALLOW_ALL);
3. onFileChooser 错误
onFileChooser要求返回FileChooserResult类型,且需实现实际文件选择逻辑,需添加file_picker依赖并修改代码:
// 先在pubspec.yaml添加依赖:file_picker: ^6.1.1 import 'package:file_picker/file_picker.dart'; // 修改onFileChooser实现 onFileChooser: (controller, params) async { final pickerResult = await FilePicker.platform.pickFiles( type: params.acceptTypes.isNotEmpty ? FileType.custom : FileType.any, allowedExtensions: params.acceptTypes, allowMultiple: params.mode == FileChooserMode.OPEN_MULTIPLE, ); if (pickerResult != null) { return FileChooserResult( files: pickerResult.files.map((file) => WebFile( name: file.name, path: file.path, bytes: file.bytes, )).toList(), ); } return null; // 取消选择时返回null },
完整修复代码
import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:file_picker/file_picker.dart'; class MyWebView extends StatefulWidget { const MyWebView({Key? key}) : super(key: key); @override _MyWebViewState createState() => _MyWebViewState(); } class _MyWebViewState extends State<MyWebView> { late final InAppWebViewController _webViewController; Future<void> _uploadFile() async { await _webViewController.evaluateJavascript(source: 'document.getElementById("myFileInput").click();'); } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: InAppWebView( initialUrlRequest: URLRequest(url: Uri.parse('https://server.institutecms.com/')), onWebViewCreated: (controller) { _webViewController = controller; }, androidOnPermissionRequest: (controller, origin, resources) async { return PermissionRequestResponse( resources: resources, action: PermissionRequestResponseAction.GRANT, ); }, onLoadStart: (controller, url) {}, onLoadStop: (controller, url) {}, onConsoleMessage: (controller, consoleMessage) { print(consoleMessage); }, shouldInterceptRequest: (controller, request) async { final response = await controller.getUrlRequest(request: request); if (response != null && (request.url?.endsWith('.css') == true || request.url?.endsWith('.js') == true)) { return WebResourceResponse( data: response.data, mimeType: response.mimeType, encoding: response.encoding, statusCode: 200, reasonPhrase: 'OK', headers: {'Access-Control-Allow-Origin': '*', ...response.headers}, ); } return response; }, onFileChooser: (controller, params) async { final pickerResult = await FilePicker.platform.pickFiles( type: params.acceptTypes.isNotEmpty ? FileType.custom : FileType.any, allowedExtensions: params.acceptTypes, allowMultiple: params.mode == FileChooserMode.OPEN_MULTIPLE, ); if (pickerResult != null) { return FileChooserResult( files: pickerResult.files.map((file) => WebFile( name: file.name, path: file.path, bytes: file.bytes, )).toList(), ); } return null; }, ), floatingActionButton: FloatingActionButton( onPressed: _uploadFile, child: const Icon(Icons.file_upload), ), ), ); } }
内容的提问来源于stack exchange,提问作者M.Shahzad
相关产品推荐
相关产品推荐

