You need to enable JavaScript to run this app. 如何用原生JS将input图片与其他信息存至localStorage并读取
优惠活动
大模型
产品
解决方案
定价
更多

如何用原生JS将input图片与其他信息存至localStorage并读取

原生JS实现图片+关联表单信息存储到localStorage的方案

核心逻辑:FileReader 读取生成的 Base64 DataURL 支持直接JSON序列化,可直接存入localStorage;原生File对象本身无法被结构化序列化,不能直接写入存储。

1. 原有图片预览逻辑改造(暂存图片读取结果)

你当前的代码读取完DataURL仅完成了预览赋值,没有暂存图片核心信息,后续组装存储数据时会无法拿到读取结果,需要在作用域内增加临时变量存储图片信息,同时补充文件类型校验:

// 作用域内临时变量,存储当前选中的图片信息
let currentSelectedImage = null;

function onFileSelected(event) {
  const selectedFile = event.target.files[0];
  // 校验是否选中图片类型文件
  if (!selectedFile.type.startsWith('image/')) {
    alert('请选择图片类型文件');
    event.target.value = '';
    return;
  }
  const reader = new FileReader();
  const imgtag = document.getElementById("food");
  imgtag.title = selectedFile.name;

  reader.onload = function(loadEvent) {
    const imageDataUrl = loadEvent.target.result;
    imgtag.src = imageDataUrl;
    // 暂存图片核心信息,供后续和表单数据组装
    currentSelectedImage = {
      fileName: selectedFile.name,
      fileSize: selectedFile.size,
      dataUrl: imageDataUrl
    };
  };
  reader.readAsDataURL(selectedFile);
}

2. 数组结构存储实现

按照数组结构优先的要求,固定一个专属存储键名,每次写入时先读取本地已有的数组,将本次新增的「图片信息+关联表单字段」对象push到数组末尾,整体序列化后写回localStorage:

// 本地存储的固定键名
const STORAGE_KEY = 'storedFoodRecords';

function saveRecordToLocal(relatedFormData) {
  // 校验是否已选中图片
  if (!currentSelectedImage) {
    alert('请先选择需要上传的图片');
    return;
  }
  // 组装单条存储对象:合并图片信息 + 其他关联表单字段
  const recordItem = {
    id: Date.now(), // 生成唯一标识,方便后续读取、删除操作
    createTime: new Date().toISOString(),
    image: currentSelectedImage,
    // 接收传入的其他表单关联信息,可任意扩展字段
    formInfo: relatedFormData
  };

  try {
    // 读取本地已有的数组,首次使用时初始化为空数组
    let storageList = [];
    const rawStorage = localStorage.getItem(STORAGE_KEY);
    if (rawStorage) {
      storageList = JSON.parse(rawStorage);
      // 兜底校验:如果本地存储被篡改导致非数组,重新初始化
      if (!Array.isArray(storageList)) {
        storageList = [];
      }
    }
    // 新记录push到数组尾部
    storageList.push(recordItem);
    // 整体序列化后写回localStorage
    localStorage.setItem(STORAGE_KEY, JSON.stringify(storageList));
    // 存储完成后重置临时状态,避免重复提交
    currentSelectedImage = null;
    document.querySelector('input[type="file"]').value = '';
    document.getElementById('food').src = '';
    alert('存储成功');
  } catch (err) {
    // 捕获常见异常:localStorage容量超限、序列化失败等
    alert(`存储失败:${err.message}`);
  }
}

// 触发存储的示例逻辑
function submitRecord() {
  // 收集其他关联表单字段,可根据实际业务扩展
  const foodName = document.getElementById('foodName').value;
  saveRecordToLocal({ foodName: foodName });
}

对应补充的HTML结构示例:

<div class="immagine_cibo">
  <input type="file" onchange="onFileSelected(event)">
  <img id="food" height="200" width="250">
  <!-- 补充的关联表单、操作按钮、渲染容器 -->
  <input type="text" id="foodName" placeholder="输入关联的食物名称">
  <button onclick="submitRecord()">提交存储</button>
  <div id="recordList" style="margin-top: 20px;"></div>
</div>

3. 存储内容读取实现

读取时直接通过固定键名拉取本地原始字符串,JSON反序列化后即可拿到完整的数组结构,存储的DataURL可直接赋值给img标签的src属性完成渲染:

function getStoredRecords() {
  const rawStorage = localStorage.getItem(STORAGE_KEY);
  if (!rawStorage) return [];
  try {
    const storageList = JSON.parse(rawStorage);
    // 兜底校验返回合法数组
    return Array.isArray(storageList) ? storageList : [];
  } catch (err) {
    console.error('读取存储失败', err);
    return [];
  }
}

// 读取后渲染到页面的示例
function renderStoredRecords() {
  const records = getStoredRecords();
  const container = document.getElementById('recordList');
  container.innerHTML = '';
  records.forEach(record => {
    const itemDom = document.createElement('div');
    itemDom.style.border = '1px solid #eee';
    itemDom.style.padding = '10px';
    itemDom.style.margin = '10px 0';
    itemDom.innerHTML = `
      <img src="${record.image.dataUrl}" style="height:100px;width:125px;">
      <p>文件名:${record.image.fileName}</p>
      <p>关联信息:${JSON.stringify(record.formInfo)}</p>
      <p>存储时间:${record.createTime}</p>
    `;
    container.appendChild(itemDom);
  })
}

// 页面加载时自动渲染已存储的内容
window.onload = renderStoredRecords;

关键注意事项

  • localStorage 单域名通常有5MB左右的容量限制,Base64格式的图片会比原文件体积大33%左右,不适合存储超大尺寸图片,需提前控制单张图片大小
  • 写入存储时必须通过JSON.stringify对数组、对象做序列化,直接存储对象会被自动转成[object Object]的无效字符串
  • FileReader为异步执行逻辑,不能在readAsDataURL调用后立刻读取图片结果,必须在onload回调拿到DataURL后再触发存储操作
  • 读取流程必须增加JSON解析的异常兜底,避免本地存储被异常篡改导致页面运行报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 20:06:03