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

Chrome扩展chrome.storage读写异常:存储无数据、读取结果未定义

智能家居Chrome扩展存储数据加载失败问题排查

问题概述

开发智能家居Chrome扩展时,需要在登录选项页和设备弹窗页之间持久化敏感数据:

  • 最初选择chrome.storage.session,控制台显示写入成功但存储无数据;
  • 切换到chrome.storage.local后,存储看似成功,但加载数据到user变量时出现Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'pref')错误,result.user为undefined。

关键信息

选项页控制台输出(确认user数据完整)

user data stored: 

devices: []
pref: {dark: true}
profile: {
    email: 'phy@sr.com', 
    first_name: 'PleasePlease', 
    id: 18616, 
    last_name: 'JustWorkTheFirstTime', 
    mobile_phone: '+15555555555', …}
session: {
    access_token: '...', 
    expires: 1680126140, 
    refresh_token: '...', 
    user_id: 181818}
units: (4) [{…}, {…}, {…}, {…}]

设备页错误信息

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'pref')

Manifest配置

{
  "manifest_version": 3,
  "name": "SmartHome extension",
  "description": "A smart device dashboard for Chrome",
  "version": "0.0.1",
  "action": {
    "default_popup": "./devices.html",
    "default_icon": "./images/logo.png"
  },
  "options_page": "./options.html",
  "options_ui": {
    "page": "./options.html",
    "open_in_tab": false
  },
  "permissions": [
    "storage"
  ],
  "host_permissions": ["https://api.smarthome.com/*"]
}

核心代码片段

存储数据方法

async #storeUser(){
    await chrome.storage.session.set({ 'user': user })  
        .then( () => {
            console.log('user data stored:', user);
        } );
}

加载数据方法

async loadUser(){
    /** @todo write this */
    await chrome.storage.session.get(["user"]).then((result) => {
        result = result.user;
        user.pref = result.pref;
        user.session = result.session;
        user.profile = result.profile;
        user.units = result.units;
        user.devices = result.devices;
        alert('user is:', user)
    });
}

排查与修复建议

1. 修复loadUser方法的空值判断

原代码未处理result.user为undefined的情况,直接读取result.pref导致报错。修改为:

async loadUser(){
    // 改用解构赋值+async/await扁平化写法,避免嵌套
    const { user } = await chrome.storage.local.get("user");
    
    // 先判断数据是否存在
    if (!user) {
        console.error("存储中无用户数据");
        return;
    }
    
    // 确保user变量已初始化,再赋值
    Object.assign(user, {
        pref: user.pref,
        session: user.session,
        profile: user.profile,
        units: user.units,
        devices: user.devices
    });
    console.log('用户数据加载完成:', user);
}

2. 验证存储数据的真实性

在设备页控制台手动执行以下命令,确认数据是否真的存入chrome.storage.local:

chrome.storage.local.get("user").then(res => console.log("存储中的用户数据:", res.user));

如果返回undefined,说明存储过程存在问题,需检查:

  • #storeUser中的user变量是否为全局变量,或是否在存储前被意外修改;
  • 存储时是否使用了正确的存储区域(比如误写为session而非local)。

3. 注意chrome.storage.session的上下文限制

Manifest V3中,chrome.storage.session的数据仅在同一上下文会话中有效,选项页和弹窗是独立的上下文,无法直接共享数据。如果要跨页面持久化敏感数据,建议:

  • 使用chrome.storage.local配合前端加密存储敏感信息;
  • 通过后台Service Worker作为中间层,统一处理存储读写。

4. 修复Promise链式调用的嵌套问题

原session方法中的fetch嵌套可能导致user未完全赋值就执行存储,重构为async/await扁平化写法:

async session(email, password){
    const body = JSON.stringify({ email, password });
    this.#setupRequest('/api/v1/sessions','POST', body);
    this.#options.headers['Content-Length'] = body.length;

    const response = await fetch(this.#url.base + this.#url.endpoint, this.#options);
    const responseBody = await response.json();
    
    user.session = responseBody.data;
    this.#options.headers.Authorization = `Bearer ${responseBody.data.access_token}`;

    await this.#getProfile();
    await this.getUnits(); // 修正原代码的语法错误
    await this.#storeUser();

    this.#reset();
    return response.status;
}

5. 检查变量作用域

确认user变量在#storeUser和loadUser中是同一个全局变量,或在模块中正确导出/导入。如果是ES模块环境,未正确导出会导致变量未定义。

内容的提问来源于stack exchange,提问作者The Jaded George

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:55:11