开源客户管理系统 SuiteCRM 点击返回按钮报错 ERR_CACHE_MISS

更新日期: 2024-10-14 阅读次数: 98 字数: 1635 分类: 管理

在公司内部署了一套开源的客户管理系统 SuiteCRM, 具体流程参考:Ubuntu Server 22.04 部署安装开源 CRM SuiteCRM 7.14

但是遇到了一个非常影响体验的问题,经常点击返回按钮报错 ERR_CACHE_MISS。

复现步骤

  1. 进入一个超过两页的列表,例如联系人列表
  2. 进入列表页第二页,即点击下一页
  3. 选择一个联系人,点击,查看详情
  4. 点击浏览器的返回按钮

此时浏览器报错:ERR_CACHE_MISS

详细报错信息

中文报错信息:

是否重新提交表单? 要正确显示此网页,请重新提交你之前输入的数据。通过执行此操作,你将重复此页面之前执行的任何操作。 刷新以重新提交加载此页面所需的数据。 ERR_CACHE_MISS

类似问题

  • https://community.suitecrm.com/t/using-browser-back-button-causes-err-cache-miss/68572/16
  • https://github.com/salesagility/SuiteCRM/issues/7321

这个是 POST 搜索操作,引起的。而且,可以在出现 ERR_CACHE_MISS 错误之后,再点一次回退按钮就能解决。

但是,我目前遇到的,解决不了。再点一次回退,实际上就回到了列表首页,而不是列表的第二页。

浏览器为何会报 ERR_CACHE_MISS 这个错误呢?

这里的解释非常详细:

https://stackoverflow.com/questions/19215637/navigate-back-with-php-form-submission

引用一下里面的例子:

  1. 用户填写表格 (form),并提交 (submit)
  2. 服务器端处理提交的 post 数据,然后返回一个新的页面,并标注不要缓存 (not cacheable)
  3. 在返回的新页面中,用户又继续进入了下一个页面 (例如上门案例中的 detail 页)
  4. 这时用户点击浏览器的回退按钮。boom 爆炸了💥

于是就报 ERR_CACHE_MISS 错误了,跟 SuiteCRM 列表页问题完全是一个流程。

如果这是一个信用卡支付账单的功能,那么点击浏览器回退按钮,会造成两次 submit 操作。 即,重复支付订单。这个肯定是一个最严重的问题。所以,这里浏览器才会明确提示 ERR_CACHE_MISS 错误。

而为啥我的博客发布文章功能,就没有这个问题呢?

这也是里面给出的一个解决方案,就是 POST 数据之后,服务器再 302 redirect 重定向到一个 GET 页面 A。 此时,用户再点击其他页面,再点击 back 按钮,就是 GET 页面 A 了,而不是重新 POST。

这个解释很完美 👏

但是,这里也不能改成 302 跳转 GET 页面。。。

那我如果把列表页的请求,由 POST 改成 GET 不就好了?

另一个 ERR_CACHE_MISS 原因的概要描述

当你导航回包含表单提交的页面(通常是POST请求)时,Chrome可能会提示你重新提交表单。如果表单数据不再存在于缓存中,浏览器无法自动重新提交它,导致 "ERR_CACHE_MISS" 错误。

解决方法一:简单粗暴的继续使用

遇到这个错误时,点击浏览器的刷新按钮,然后在弹出的确认框中,点击继续。就能正常了。。。

但是每次遇到,都需要这样操作。体验还是非常糟糕的。

或者点击详情时,在新 tab 页中打开。

解决方法二:禁用浏览器的缓存

F12 打开开发者工具,在网络工具里,勾选"禁用缓存"。

这样,这个 ERR_CACHE_MISS 错误就不会再出现了。但是,由于 SuiteCRM 页面内的加载项太多,禁用后, 页面刷新缓慢。大量静态资源文件都需要重新从服务器拉取。

解决方法三:修改 SuiteCRM 源码

最后,还是通过修改 SuiteCRM PHP 源码的方式解决了,详细参考我整理的:

大结局:修改 PHP 代码解决 SuiteCRM ERR_CACHE_MISS 错误

下面的部分可以忽略了。

发送了个什么请求

引起这个错误时,对应的请求是什么?即,从详情页,返回列表时,到底是在调用哪个接口?

没有 GET/POST 信息,不知道是 GET 还是 POST

https://crm.sunzhongwei.com/index.php
  • 请求头里没有 Cache-Control 及 Pragma 信息
  • 响应头为空

第一次进入第二列表时, 正常的请求

请求:

POST https://crm.sunzhongwei.com/index.php
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded

响应头:

Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=UTF-8

禁用浏览器缓存之后的正常请求

请求头:

POST https://crm.sunzhongwei.com/index.php
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/x-www-form-urlencoded

响应头:

Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache

列表首页为何是正常的

列表首页,在进入详情页,再返回时,就是正常的,没有这个错误。来看看首页的请求。

请求头:

  • 请求头里没有 Cache-Control 及 Pragma 信息
GET https://crm.sunzhongwei.com/index.php?module=Contacts&action=index

响应头:

Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache

用我的博客来模拟

很奇怪,这么多年,第一次遇到这个问题。写过很多网站,也一次没有到这个错误。

于是我用博客的编辑页测试了一下:

POST 发布成功,然后点击浏览器 back 按钮。

请求

GET https://www.sunzhongwei.com/edit/aspnet-core-80-asp-append-version

提示,显示临时标头。禁用缓存以查看完整的标头。

响应头:

cache-control: no-cache, private
200 OK (从磁盘缓存)

但这并不是一回事,因为 SuiteCRM 是通过 POST 拉取列表,我这个博客是通过 GET 拉取编辑页。

浏览器 http 请求头 Cache-Control 有哪些值,区别是什么

请求时,Cache-Control 设置为 no-cache 与 max-age=0 有什么区别?

max-age=0 is a workaround for no-cache, because many old (HTTP/1.0) cache implementations don't support no-cache. Recently browsers are still using max-age=0 in "reloading" — for backward compatibility

Pragma: no-cache 有什么用,跟 Cache-Control:no-cache 有什么区别

  • Pragma: no-cache:是 HTTP/1.0 的遗留指令。虽然许多现代浏览器和服务器仍然支持它,但它主要是为了向后兼容较旧的 HTTP/1.0 应用程序和设备。在 HTTP/1.1 及更高版本的环境中,Cache - Control头是推荐的缓存控制方式。
  • Cache-Control: no-cache:是 HTTP/1.1 引入的缓存控制头。它提供了更灵活和精细的缓存控制机制,并且在现代的网络应用中被广泛使用。

参考

  • https://world.siteground.com/kb/err_cache_miss
  • https://stackoverflow.com/questions/19215637/navigate-back-with-php-form-submission
  • https://www.cnblogs.com/cyamazing/p/18246375

微信关注我哦 👍

大象工具微信公众号

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

tags: CRM 企业数字化