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

Flutter WebViewPlus调用JS函数遇localStorage禁用问题求助

解决WebViewPlus中data URL下localStorage禁用的问题

错误原因

你遇到的错误根源在于:用controller.loadString()加载HTML内容时,WebView会把内容打包成data:text/html,...格式的URL,而浏览器出于安全限制,会直接禁止这类URL访问localStorage,导致第三方JS库调用存储时触发权限报错。

解决方案

方案1:将HTML存为本地资产文件加载(推荐)

这种方式彻底避开data URL的限制,是最可靠的解决办法:

  1. 配置项目资产声明
    在项目根目录的pubspec.yaml中添加资产配置:
flutter:
  assets:
    - assets/payment_dashboard.html
  1. 创建本地HTML文件
    在项目根目录新建assets文件夹,里面创建payment_dashboard.html文件,把你的HTML代码复制进去:
<!DOCTYPE html>
<html>
<head>
<script src="https://bla.blabla.io/bla.js"></script>
</head>
<body>
<div id="savingContainer"></div>
<script>
function myFunction() {
 const credentials = {
      token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
     }
    Zwitch.openSavingsAccount({
      containerId: 'savingContainer',
      credentials: credentials,
      callbacks: {
        onSuccess: (resp) => { console.log(resp); },
        onError:  (resp) => { console.log(resp); },
      }
    });
}
</script>
<h1>My First Heading</h1>
<button onclick="myFunction()">Submit</button>
</body>
</html>
  1. 修改Dart代码加载本地资产
    替换原来的loadString方式,改用initialUrl加载本地资产,同时配置Android和iOS的存储权限:
import 'package:flutter/material.dart';
import 'package:webview_flutter_plus/webview_flutter_plus.dart';

class WebViewStorage extends StatelessWidget {
  const WebViewStorage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WebViewPlus(
        javascriptMode: JavascriptMode.unrestricted,
        initialUrl: 'assets/payment_dashboard.html',
        // Android端开启存储相关权限
        androidSettings: AndroidSettings(
          domStorageEnabled: true,
          databaseEnabled: true,
          allowFileAccess: true,
          allowContentAccess: true,
        ),
        // iOS端开启存储权限
        iosSettings: IosSettings(
          domStorageEnabled: true,
          sharedStorageEnabled: true,
        ),
      ),
    );
  }
}

方案2:配置WebView存储(仅作备选,可能不稳定)

如果必须用loadString加载字符串HTML,可以尝试添加存储配置,但由于data URL的固有安全限制,部分场景可能仍无法正常工作:

import 'package:flutter/material.dart';
import 'package:webview_flutter_plus/webview_flutter_plus.dart';

class WebViewStorage extends StatelessWidget {
  const WebViewStorage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WebViewPlus(
        javascriptMode: JavascriptMode.unrestricted,
        // Android端配置存储
        androidSettings: AndroidSettings(
          domStorageEnabled: true,
          databaseEnabled: true,
          allowFileAccess: true,
        ),
        // iOS端配置存储
        iosSettings: IosSettings(
          domStorageEnabled: true,
          sharedStorageEnabled: true,
        ),
        onWebViewCreated: (controller) {
          controller.loadString('''<!DOCTYPE html>
<html>
<head>
<script src="https://bla.blabla.io/bla.js"></script>
</head>
<body>
<div id="savingContainer"></div>
<script>
function myFunction() {
 const credentials = {
      token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
     }
    Zwitch.openSavingsAccount({
      containerId: 'savingContainer',
      credentials: credentials,
      callbacks: {
        onSuccess: (resp) => { console.log(resp); },
        onError:  (resp) => { console.log(resp); },
      }
    });
}
</script>
<h1>My First Heading</h1>
<button onclick="myFunction()">Submit</button>
</body>
</html>

   ''');
        },
      ),
    );
  }
}

注意事项

  • Android和iOS的WebView存储配置是独立的,两个平台都需要设置到位;
  • 优先选择方案1,因为data URL的安全限制是浏览器内核的固有规则,方案2无法彻底覆盖所有场景的问题。

内容的提问来源于stack exchange,提问作者Rafi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:56:41