You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:25:26