加购按钮点下去,页面也提示「已加入购物车」,再打开购物车却是空的;或者右上角数量跳了一下又回到 0;登录用户刷新后看到的是一辆被冻住的空车;更麻烦的是,结账页里出现了别的访客的商品,或两个浏览器互相串了会话。团队第一反应常常是清整站缓存、给 CDN 打开 Cache Everything,或再装一个「全站加速」插件。这和近期已发的 WooCommerce 结账页空白或支付按钮点了没反应 、结账一直转圈或改地址卡住 、运费不显示或为 0 、优惠券无效 、产品页打开很慢 、后台订单列表打开很慢或批量改状态卡住 、更新插件后按钮没反应或表单结账突然失效 、启用 Redis 对象缓存后仍慢或出现陈旧数据 、改了报价客户还看见旧版 、支付成功但订单仍待付款或不扣库存 不是一类故障。「结账页空白或支付按钮没反应」是最接近的一篇,它卡的是结账页 HTML 被整页缓存后页面空白、按钮点了没反应;「结账一直转圈」慢在 update_order_review、运费或支付接口;「运费为 0 / 优惠券无效」先核配送区域和优惠券条件;「产品页慢」和「后台订单列表慢」是查询与任务拆分,今日那篇后台订单列表虽和本文共用同一枢纽页,切口是后台查询和导出,不是前台会话;「更新插件后交互断了」要先留日志再二分定位冲突插件;「对象缓存后仍慢或陈旧」和「五层缓存后客户看见旧版报价」分别是前台性能、内容页被冻住,不是购物车会话;「支付成功但订单仍待付款」要查 webhook 与库存回写。本文切口不同:加购看起来成功,但购物车是空的、数量不对,或结账、会话串到了别的访客 ------前提是购物车、结账、我的账户,以及任何携带 woocommerce_items_in_cart、wp_woocommerce_session_ 的请求,都必须绕过页面缓存和 CDN;目录页和产品页仍可对未登录、尚未加购的访客整页缓存。不要把「结账页被冻成空白」和「会话被错误缓存或串了」混成同一次改动。本篇未取得可核验的百度指数或微信指数实时数值,也不用这类数字决定要不要先核 Cookie。
适用场景
本文适用于:WooCommerce 站点在启用或调整页面缓存、CDN、对象缓存之后,或刚完成克隆、迁移之后,前台加购提示成功,但购物车是空的、购物车数量与实际不符、登录用户看到被冻结的空车,或结账、会话串到了别的访客。常见于给全站打开了 Cache Everything、把购物车或结账路径写进了页面缓存、Cookie 的域名或路径在 www 与裸域、主域与子目录之间不一致,以及把站点复制到新环境后对象缓存前缀没有改成站点独有。有时只在无痕窗口或未登录时出现,登录后看起来正常;有时只在加购之后的第二次打开购物车时复现。不适用于:结账页整页空白或支付按钮点了没反应(按结账被页面缓存、主题与支付网关脚本冲突那篇收口);结账一直转圈、改地址卡住(按结账链路请求耗时、运费和支付接口那篇收口);运费不显示或为 0、优惠券无效(按配送区域、运费类和优惠券条件收口);产品页慢或后台订单列表慢(按查询与任务拆分收口);更新插件后按钮、表单或结账交互断了但购物车会话本身是对的(按插件冲突那篇收口);Redis 启用后前台仍慢或内容页陈旧(按对象缓存连接、前缀与 drop-in,或五层缓存那篇收口);支付成功但订单仍待付款、库存未扣(按 webhook 收口)。那些按各自专题处理,别和「会话 Cookie 与缓存排除没配对」混改。
先分清:购物车页被整页缓存 vs 带会话 Cookie 的请求被 CDN 缓存 vs Cookie 域/路径不一致 vs 迁移后对象缓存前缀串会话
常见落在四条线上:
- 购物车、结账、我的账户被整页缓存 :页面缓存插件把
/cart/、/checkout/、/my-account/的 HTML 冻住了。未登录访客看到的是一份空车快照,或上一名访客留下的车;加购接口其实写过会话,但再打开页面时读到的是缓存里的空车。 - 带会话 Cookie 的请求被 CDN Cache Everything :即使源站排除了购物车路径,CDN 仍把带
woocommerce_items_in_cart或wp_woocommerce_session_的响应缓存并共享给其他人。表现为无痕窗口里加购成功,换一个网络或清 Cookie 后再打开却看到别人的车,或自己的车时有时无。 - Cookie 域或路径不一致 :站点同时可从
www与裸域访问,或从子目录迁到根路径后,COOKIE_DOMAIN、Cookie Path 仍指向旧值。加购在一个主机名下写入会话,购物车页却在另一个主机名下读取,看起来就是「刚加进去,换个入口就空了」。 - 迁移或克隆后对象缓存前缀串会话:Redis 等对象缓存能加速无法整页缓存的购物车和结账,但前缀必须按站点唯一。两套站点共用同一个 Redis 库却共用前缀,或从生产复制到预发后没改前缀,就会把会话、购物车片段取串。这和「启用对象缓存后前台仍慢」不是同一件事:本文要先确认有没有把别人的会话读过来。
先记下:故障是在打开页面缓存、CDN 或对象缓存之后出现的,还是迁移之后才出现的;受影响的是空车、数量不对,还是串了别人的商品;无痕窗口和已登录窗口是否表现一致。明确这是 会话被错误缓存或读串了,不是结账页 HTML 被冻成空白,也不是后台订单列表慢。

第一步:先核页面缓存排除与会话 Cookie
不要先关全站缓存,也不要先换主题或叠加新的加速插件。先核对排除规则和 Cookie 是否成对出现:
- 确认必须绕过页面缓存的路径 :购物车、结账、我的账户这三条路径不能整页缓存。目录页和产品页可以对未登录、还没有加购的访客缓存;一旦请求带上
woocommerce_items_in_cart或wp_woocommerce_session_,这一次请求就必须绕过页面缓存。规则写反了,先改规则,而不是先清整站。 - 在无痕窗口里看 Cookie 有没有写上 :加购一次后打开开发者工具的 Application 或 Storage,确认出现了
woocommerce_items_in_cart(或同类购物车标记)以及wp_woocommerce_session_前缀的会话 Cookie,Path 一般为/,Domain 与当前访问主机名一致。如果加购提示成功但这两类 Cookie 根本没出现,先查是否被缓存插件、安全插件或服务器规则拦掉 Set-Cookie,而不要先怀疑主题模板。 - 对照缓存插件的排除与 Cookie 规则:在常见页面缓存插件里,确认购物车、结账、账户路径在排除列表中,并且对上述 Cookie 选择「不缓存该请求」。不要只排除路径而忽略 Cookie------加购后用户往往还在产品页或首页,这些页面一旦被整页缓存,购物车数量和迷你购物车也会被冻住。
- 和「结账页空白」那篇分开:如果打开结账页是空白、支付按钮点了没反应,优先按结账页 HTML 被整页缓存、主题或支付网关脚本冲突处理。本文如果页面能打开、只是车是空的或商品不是自己的,先留在会话和排除规则上。
- 改规则之前先留回滚点 :调整缓存插件或
wp-config.php里的 Cookie 常量前,备份当前缓存规则和配置,或确认主机快照可用。没有回滚点,就不要在生产上连续开关全站缓存。
预期:能说清「购物车、结账、账户是否已被排除,加购后两类会话 Cookie 是否出现,当前访问的主机名与 Cookie 域是否一致」;还没有在生产上关闭全部缓存或更换缓存插件。
缓存排除和会话核对的细节,可对照 WooCommerce 购物车与结账路径的缓存排除与会话核对要点 里按页面类型拆开的步骤,不必同时改主题、CDN 和对象缓存。
第二步:查 CDN Cache Everything 与 Cookie 域、路径
源站规则看起来正确,仍出现空车或串会话时,把 CDN 和 Cookie 作用域单独拿出来看:
- CDN 不要对带会话 Cookie 的请求做 Cache Everything :在 CDN 控制台里,Cache Everything、整站 HTML 缓存如果没有按 Cookie 绕过,就会把带
woocommerce_items_in_cart、wp_woocommerce_session_的响应缓存下来,再发给下一个访客。给购物车、结账、我的账户做 Bypass,并对这两类 Cookie 建「存在则绕过缓存」的规则;不要只按 URL 排除,因为加购后的产品页、分类页同样可能带着会话 Cookie。 - 改完后必须清页面缓存和 CDN,再在无痕窗口复测:只改规则不清缓存,旧的空车 HTML 还会被命中。清完后用无痕窗口加购、打开购物车、走到结账前一步,再换一个无痕窗口确认看不到上一个会话的商品。
- 统一主机名,核对 Cookie 域和路径 :若站点可同时用
www与裸域、http 与 https 打开,先做 301 统一到一个主机名和协议。检查COOKIE_DOMAIN、Cookie Path 是否仍指向旧域名或旧的子目录。加购和查看购物车必须在同一个主机名下完成,避免一边写入、另一边读不到。 - 看购物车片段请求有没有被缓存或误拦 :页头数量、迷你购物车常常走
wc-ajax=get_refreshed_fragments(或同类 cart fragments 请求)。若这条请求被页面缓存、CDN 或安全规则冻住、拦成 403,就会出现「加购提示成功,数量却不更新,再进购物车是空的或还是旧的」。在 Network 里看这次请求是否 200、是否带回当前会话,而不是只刷新购物车页面。
预期:CDN 对带会话 Cookie 的请求不再共享缓存;主机名与 Cookie 域一致;cart fragments 能按当前会话刷新;无痕复测里加购后的车是自己的,且不会出现在下一个无痕窗口里。
第三步:查迁移后的对象缓存前缀,并回归关键路径
页面缓存和 CDN 排除已经正确,仍出现串会话或空车时,再查对象缓存:
- 对象缓存可以给购物车和结账加速,但前缀必须按站点唯一 :Redis 一类对象缓存对无法整页缓存的购物车、结账和登录请求是有帮助的。启用后加购、优惠券和会话都要回归。克隆、迁移或预发从生产复制而来时,检查对象缓存插件里的前缀(例如
WP_REDIS_PREFIX)以及数据库表前缀是否改成了当前站点独有,避免两套站点共用同一个 Redis 库和同一段前缀。这不是在解决「启用对象缓存后前台仍慢」,而是避免把另一套环境里的会话读过来。 - 确认 drop-in 连的是当前环境 :
object-cache.php若还指向旧主机、旧数据库编号,或预发和生产抢同一组键,也会表现为购物车时有时无、登录用户看到过期空车。先改前缀和连接,再清对象缓存,而不是先删掉 drop-in 指望整站变快。 - 登录和未登录都要走完加购到结账前一步:未登录无痕加购、刷新购物车、再打开结账;登录后再加一件,确认数量、商品和价格是当前用户的。不要只看首页迷你购物车的数字。
- 把改动写进运维记录:排除了哪些路径和 Cookie、CDN 规则怎么改、Cookie 域是否统一、对象缓存前缀改成了什么。下次再开 Cache Everything 或做迁移时才有对照。独立站排障时不必先换一套缓存插件,DEVDIY 在同类站点里也是先核排除规则和会话,而不是先叠加新的加速方案。
第四步:验收与回滚
改完后用下面几条核对,而不是只看「加购提示成功」:
- 无痕窗口加购后,购物车里是刚加入的商品,数量与页头一致;再开一个无痕窗口,不应看到上一会话的商品。
- 登录用户刷新后不会回到一辆被冻住的空车;结账页商品、价格与购物车一致,没有串到别人的会话。
- 带
woocommerce_items_in_cart或wp_woocommerce_session_的请求在页面缓存和 CDN 上是绕过,而不是 HIT。 wc-ajax购物车片段请求返回当前会话的数据,状态码正常。- 若动过对象缓存,前缀已是当前站点独有,预发与生产不再共用同一组键。
- 改规则前的备份或快照仍可回滚;如果回滚后空车或串会话立刻消失,说明定位方向是对的,再安排正式修复。

先把「加购后车是空的或会话串了」和结账页空白、结账转圈、内容页陈旧、后台订单慢这些专题分开,再按排除规则、Cookie、CDN 和对象缓存前缀收口,通常就能避免用全站清缓存把还能下单的店铺越改越乱。