页面缓存导致数据错误

服务端渲染(ssr)会将 API 数据做页面元素返回给前端, 而浏览器会认为是静态页面并将页面缓存, 导致每次访问时都是缓存用户数据. 页面又包含对数据的处理并提交.
当多端更新时由于可能不是以最新数据修改提交就会出现数据相互覆盖而出错.

问题背景

作为一名互联网的爱好者, 曾经收藏很多网址, 用过浏览器链接收藏功能, Google 账号登录不上(由于被墙), 导致链接无法同步. 多浏览器之间无法共享收藏, 也曾为转门
写一篇博客去分类记录, 但太不方便使用, 接着也放弃了. 上网多年的收藏渐渐的散了. 于是决心自己实现一个链接收藏管理功能.

需求设计

  1. 链接页管理页做为首页, 访问简单的域名便可 https://wxaxiaoyao.cn
  2. 提供系统默认链接和用户自定义链接, 用户自定义支持未登录使用, 链接支持分类
  3. 多端编辑自动同步合并(需登录)
  4. 页面服务端渲染, 提升用户体验

需求分析

需求1略过, 需求2未登录使用自定义功能, 可借助localStorage存储实现, 需求3多端编辑可将数据存于后端DB, 数据合并其实远程数据与本地缓存数据合并, 可借助更新时间
实现, 谁时间最新用谁的数据, 需求4前端框架使用nuxt解决

设计实现

数据结构设计

由于用户收藏的链接数量是有限的, 且链接数据大小不大, 需求目的侧重管理与检索. 故直接使用 mysql 的json字段存贮, 无需拆分多表(拆分多表反而是表记录剧增影响数据获取). 大致 json 格式如下:

{classify: [   // 分类列表{   // 分类项name: "分类名",links: [{text: "链接名称",url:"链接地址",tiemstamp: "更新时间戳" }]}]
}

合并数据

合并数据伪代码(由于本人英文水平较差, 变量命名可能比较糟糕, 努力改进中...), 直接复制的项目代码, 重在表达逻辑实现:

mergePageData() {const indexPageData = this.indexPageData;  // 缓存数据const selfPageData = this.selfPageData;   // 远程数据if (selfPageData.userId == undefined) {   // 未认证 远程数据为空this.selfPageData = indexPageData;    // 用缓存数据替换远程数据this.setIndexPageData(this.selfPageData);  // 缓存最新远程数据return ;};// 缓存数据属于用户且与当前认证用户不同, 用最新的远程数据替换缓存数据并缓存if (indexPageData.userId && indexPageData.userId != selfPageData.userId) return this.setIndexPageData(selfPageData);// 缓存数据不属于用户或属于当前用户则合并数据  原则将本地最新数据更新至远程数据中_.each(indexPageData.classify || [], o => {const classify = _.find(selfPageData.classify || [], x => x.name == o.name);  // 查找分类是否存在if (!classify) return selfPageData.push(o);  // 不存在直接添加_.each(o.links || [], l => {            // 存在合并链接const link = _.find(classify.links || [], x => x.text == l.text); // 查找链接项if (!link) return classify.links.push(l);  // 不存在添加if ((link.timestamp || 0) <= (l.timestamp || 0)) {  远程更新时间小于本地更新时间, 则更新链接项link.timestamp = l.timestamp;link.url = l.url;}});});this.setIndexPageData(selfPageData);  // 刷新缓存
}

问题(bug)

回到本文开头, 由于后端渲染导致浏览器缓存页面数据, 从而缓存了用户数据, 导致页面增改删链接项都是基于旧的远程数据, 多端编辑提交时相互覆盖出错. 如何解决和规避此问题?
应该可以从如下两种的方法解决:

  1. 禁止浏览器缓存页面

设置禁止缓存页面的响应头, 此方法在页面经过多层代理时可能会很麻烦

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
  1. 前端渲染时动态拉取用户数据

若对于用户自定义链接数据的SSR需求不是很强烈, 可以牺牲下做前端动态拉取渲染. 很可以保留 SSR 但还是得加客户端动态拉取逻辑.

TODO

针对缓存问题是否存在其它解决方案? 数据结构设计是否合理?

转载于:https://www.cnblogs.com/--xiaoyao--/p/11268944.html

页面缓存导致数据错误相关推荐

  1. IE浏览器下ajax缓存导致数据不更新的解决方法

    IE浏览器下ajax缓存导致数据不更新的解决方法 参考文章: (1)IE浏览器下ajax缓存导致数据不更新的解决方法 (2)https://www.cnblogs.com/xcsn/p/4745437 ...

  2. IE缓存导致数据不能实时更新的解决办法

    查看全文 http://www.taodudu.cc/news/show-5902634.html 相关文章: IE缓存设置问题 清除IE缓存 关于IE缓存所带来的数据不能实时更新的解决办法 解决ie ...

  3. c语言电子表格复制数据错误循环冗余检查,数据错误、循环冗余检查、出现“数据错误”无法复制怎么解决?...

    数据错误 循环冗余检查.出现"数据错误"无法复制; 问题描述:将文件从一个盘符复制到另一个盘符或将硬盘中的文件数据复制到可移动磁盘,如U盘等设备中时,系统提示"无法复制: ...

  4. vue切换路由页面数据缓存_Vue-Router实现前端页面缓存

    一.使用情景 在使用Vue开发单页面应用时,我们通常会使用Vue-Router进行页面导航,Vue-Router在进行路由切换的时候,页面是会重新加载,对应的生命周期函数也会再次执行一遍,但是在有些业 ...

  5. HTTP缓存解释为何页面响应的数据和服务端的不一致

    HTTP缓存解释为何页面响应的数据和服务端的不一致 用途 HTTP缓存主要用在对一些实时性要求不高的静态文件进行的缓存,往往都是存在浏览器端,防止这些"多余"的请求重复的访问服务器 ...

  6. 技术实践丨如何解决异步接口请求快慢不均导致的数据错误问题?

    本文分享自华为云社区<如何解决异步接口请求快慢不均导致的数据错误问题?>,原文作者:Kagol . 引言 搜索功能,我想很多业务都会涉及,这个功能的特点是: 用户可以在输入框中输入一个关键 ...

  7. 页面相关的数据存储(缓存及Web Storage)

    页面可用的缓存包括:Http Cache, Local Storage, Session Storage以及Application Cache. 它们都可以用来减少请求数量,以提高页面的性能及减少流量 ...

  8. ajax浏览器操作发生异常,解决IE浏览器缓存导致AJAX请求数据异常

    IE10浏览器会把AJAX请求的数据都缓存下来,然后每次想去刷新数据时发现数据都是一样的,于是导致数据显示异常. 解决方法: 在页面 标签里,加上以下声明: 保存后,刷新页面,重新访问即可. 说明:最 ...

  9. 一种页面数据错误输入提示方法 【转】

    一种页面数据错误输入提示方法 不是很好,但是可以用.用于效验用户输入的数据,给出适当的提示.如整数,日期时间如果用户输入错误,均需要提示用户. aspx网页中 <table cellspacin ...

最新文章

  1. 04--MySQL自学教程:数据库MySQL--【数据库DB】和【数据库管理系统DBMS】简介
  2. java 漏洞挖掘_Apache Tika命令注入漏洞挖掘
  3. java 电子商务云平台b2b b2c o2o springmvc+mybatis+spring cloud+spring boot
  4. MyBatis框架学习笔记01:初探MyBatis实现简单查询
  5. 吴恩达机器学习系列23:基于内容的推荐算法
  6. 250分b区计算机专硕,2021兰州大学研究生复试分数线
  7. c语言spi测试代码,C语言程序SPI
  8. mysql 恢复同步_常见MySQL同步错误恢复方法
  9. Oracle12c用户名scott,Oracle12c新特性pdborcl,如何登录到普通用户scott ?
  10. android 默认分辨率是多少合适,Bluestacks分辨率修改多少合适
  11. 状态压缩DP 图文详解(一)
  12. vue+three.js导入obj模型不显示问题
  13. Freecad的Python脚本
  14. 【Java学习笔记】常用API(String、ArrayList)
  15. 互联网界的IT巨变:从DOS的编辑器,到如今的无代码开发
  16. Android实现截屏和截长图功能的几种方法
  17. 2019年4月10日
  18. ROS环境下Baxter机器人控制记录
  19. onlyoffice 源码编译,破解20连接数限制,并部署到centos7
  20. 图片预加载与addLoadEvent

热门文章

  1. 如何比较 Java 的字符串
  2. Centos6.9以下查看端口占用情况和开启端口命令
  3. Filter在Vue,JS,JQ中的使用
  4. InSAR 处理软件
  5. 个人项目的设计与分析——类饿了么、美团式订餐类校园食堂版App“加个蛋”。...
  6. Jquery validate验证表单时多个name相同的元素只验证第一个的问题
  7. Windows Server 2012 下安装MySQL 5.6 X64位包
  8. topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
  9. 栈的应用实例——计算后缀表达式
  10. 分享我第一次做项目的感受