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

Flutter中使用WebViewController.runJavaScript存储登录凭证至WebView localStorage失败

解决webview_flutter中localStorage写入失败的问题

问题核心原因

你当前的代码存在两个关键问题导致登录凭证无法写入localStorage:

  1. 执行时机错误:在initState中直接调用runJavaScript时,WebView页面还未加载完成,此时页面上下文不存在,JS代码无法生效。
  2. JS语法问题:注释中的代码直接将对象传入localStorage.setItem,但localStorage仅支持存储字符串类型,必须用JSON.stringify转换对象。

控制台的Cannot read properties of null (reading 'd')错误,是网页代码尝试读取未写入成功的localStorage数据引发的空指针异常。

修复方案

1. 调整JS执行时机

将写入localStorage的代码移至NavigationDelegate的onPageFinished回调中,确保页面完全加载后再执行JS操作。

2. 修正JS语法

统一使用localStorage.setItem方法,确保所有存储内容为字符串类型(对象需转为JSON字符串)。

完整修复代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:convert';
import 'model_response.dart';

class MyPageWidget extends StatefulWidget {
  MyPageWidget(
      {super.key,
      required this.data,
      required this.totalStep,
      required this.poster,
      required this.id});
  List<Data> data;
  int totalStep;
  String poster;
  String id;
  @override
  State<MyPageWidget> createState() => _MyPageWidgetState();
}

class _MyPageWidgetState extends State<MyPageWidget> {
  late WebViewController controller;

  @override
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {},
          onPageStarted: (String url) {},
          // 页面加载完成后执行JS写入localStorage
          onPageFinished: (String url) async {
            await controller.runJavaScript('''
              localStorage.setItem('token', ${jsonEncode(widget.id)});
              localStorage.setItem('user', JSON.stringify({
                "userData": {
                  "_id": "63d8a45c8acb9efbdce5d8ec",
                  "email": "test@gmail.com",
                  "password": "123"
                },
                "message": "User Login Successfully"
              }));
            ''');
            // 可选:验证写入结果
            final token = await controller.runJavaScriptReturningResult('localStorage.getItem("token")');
            print('已存储的token:$token');
          },
          onWebResourceError: (WebResourceError error) {},
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://www.babylonjs.com/demos/gui/')) {
              return NavigationDecision.prevent;
            }
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse('http://192.168.1.55:3000/model'));
  }

  @override
  void dispose() {
    super.dispose();
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: WebViewWidget(
          controller: controller,
        ),
      ),
    );
  }
}

额外注意事项

  • 如果widget.id包含单引号、换行等特殊字符,使用jsonEncode()做转义处理,避免JS语法错误。
  • 确保网页域名无跨域限制,本地调试通常无需额外配置,正式环境需检查CORS规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:20:40