Varnish与PrestaShop配置异常:无法进入后台及购物车无法保存
PrestaShop + Varnish 配置问题解决:后台无法访问及购物车不保存
问题描述
基于PrestaShop专用的Varnish配置文件设置时,出现两个核心问题:
- 无法进入PrestaShop后台管理页面
- 商品添加到购物车后,购物车内容无法保存
当前使用的VCL配置片段
# 为静态文件禁用Cookie if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|pdf)$" && ! (req.url ~ "\.(php)") ) { unset req.http.Cookie; return (hash); } # 对非常规HTTP方法使用管道模式 if (req.method !~ "^GET|HEAD|PUT|PATCH|POST|TRACE|OPTIONS|DELETE$") { return(pipe); } if (req.method == "GET" && (req.url ~ "^/?mylogout=")) { unset req.http.Cookie; return (pass); } # 不对PrestaShop后台页面进行缓存 if (req.method == "GET" && (req.url ~ "^/admin")) { return (pass); } # 不对自定义目录进行缓存 if (req.method == "GET" && (req.url ~ "^/custom")) { return (pass); } # 不对客户相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/authentification" || req.url ~ "^/mon-compte")) { return (pass); } # 不对客户相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/informations" || req.url ~ "^/unt.php")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/commande" || req.url ~ "^/historique")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/adresse" || req.url ~ "^/order-detail.php")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/order-confirmation.php" || req.url ~ "^/order-return.php")) { return (pass); } # 不对模块页面进行缓存 if (req.method == "GET" && req.url ~ "^/module") { return (pass); } if (req.method != "GET" && req.method != "HEAD") { return (pass); }
问题分析与解决方案
1. 后台无法访问的修复
当前配置仅对GET请求的/admin路径做透传处理,但后台登录、表单提交等操作会用到POST/PUT等方法,这些请求未被正确放行;另外PrestaShop默认会生成随机后台路径前缀(如adminabc123),如果你的后台路径不是/admin,规则也会失效。
修改方案:
- 移除后台规则中的
req.method == "GET"限制,确保所有请求方法下的后台路径都直接透传至后端 - 将
^/admin替换为你实际的后台路径前缀(可查看PrestaShop根目录下的后台文件夹名称)
修改后的后台规则:
# 不对PrestaShop后台页面进行缓存,所有请求方法均透传 if (req.url ~ "^/admin") { # 替换为你的实际后台路径,比如^/adminabc123 return (pass); }
2. 购物车无法保存的修复
购物车依赖Cookie识别用户,操作多为POST请求,当前配置虽对非GET/HEAD请求做透传,但部分购物车相关的GET请求(如查看购物车)可能被错误缓存,导致内容无法保留。
添加以下规则(放在订单相关规则之后):
# 不对购物车相关页面进行缓存,保留用户Cookie if (req.url ~ "^/panier" || req.url ~ "^/ajax-cart" || req.url ~ "^/add-cart") { # 匹配你实际的购物车路径 return (pass); }
额外检查:
- 确认静态文件规则未误匹配购物车相关的PHP请求(当前规则已排除
.php文件,无需修改) - 后端服务器的Session/Cookie配置正常,未被Varnish拦截
完整修改后的核心VCL片段
# 为静态文件禁用Cookie if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|pdf)$" && ! (req.url ~ "\.(php)") ) { unset req.http.Cookie; return (hash); } # 对非常规HTTP方法使用管道模式 if (req.method !~ "^GET|HEAD|PUT|PATCH|POST|TRACE|OPTIONS|DELETE$") { return(pipe); } if (req.method == "GET" && (req.url ~ "^/?mylogout=")) { unset req.http.Cookie; return (pass); } # 不对PrestaShop后台页面进行缓存,所有请求方法均透传 if (req.url ~ "^/admin") { # 替换为实际后台路径 return (pass); } # 不对自定义目录进行缓存 if (req.method == "GET" && (req.url ~ "^/custom")) { return (pass); } # 不对客户相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/authentification" || req.url ~ "^/mon-compte")) { return (pass); } # 不对客户相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/informations" || req.url ~ "^/unt.php")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/commande" || req.url ~ "^/historique")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/adresse" || req.url ~ "^/order-detail.php")) { return (pass); } # 不对订单相关页面进行缓存 if (req.method == "GET" && (req.url ~ "^/order-confirmation.php" || req.url ~ "^/order-return.php")) { return (pass); } # 不对购物车相关页面进行缓存,保留用户Cookie if (req.url ~ "^/panier" || req.url ~ "^/ajax-cart" || req.url ~ "^/add-cart") { # 匹配实际购物车路径 return (pass); } # 不对模块页面进行缓存 if (req.method == "GET" && req.url ~ "^/module") { return (pass); } if (req.method != "GET" && req.method != "HEAD") { return (pass); }
内容的提问来源于stack exchange,提问作者Jonatito M. Estevez
相关产品推荐
相关产品推荐

