You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Cookie的多语言站点本地化重定向:Varnish配置替代Next.js中间件方案咨询

基于Cookie的多语言站点本地化重定向:Varnish配置替代Next.js中间件方案咨询

看起来你已经找准了方向——把Next.js中间件的Cookie驱动重定向逻辑迁移到Varnish,确实能解决非Vercel环境(比如Docker独立部署)下的兼容性问题。我来帮你完善这份VCL配置,让它完全匹配你原Next.js中间件的业务逻辑:

完整Varnish VCL配置

vcl 4.1;
import cookie;

# 定义你的默认语言(根据实际站点配置修改,比如"en")
set req.http.default_locale = "en";

sub vcl_recv {
    # 跳过API、Next.js静态资源和带文件后缀的请求,直接透传
    if (req.url ~ "^/_next" || req.url ~ "^/api/" || req.url ~ "\.(.*)$") {
        return (pass);
    }

    # 从URL中提取当前语言标识:默认语言的URL不带前缀
    if (req.url ~ "^/[a-z]{2}/") {
        set req.http.locale = regsub(req.url, "^/([a-z]{2})(/.*)?$", "\1");
        # 提取URL的路径部分(去掉语言前缀)
        set req.http.path_without_locale = regsub(req.url, "^/[a-z]{2}(/.*)?$", "\2");
        # 处理根路径情况(比如/fr/会被替换成空,这里修正为"/")
        if (req.http.path_without_locale == "") {
            set req.http.path_without_locale = "/";
        }
    } else {
        # URL不带语言前缀,默认使用站点默认语言
        set req.http.locale = req.http.default_locale;
        set req.http.path_without_locale = req.url;
    }

    # 提取NEXT_LOCALE Cookie的值
    set req.http.localeCookie = "";
    if (req.http.cookie) {
        cookie.parse(req.http.cookie);
        set req.http.localeCookie = cookie.get("NEXT_LOCALE");
        # 重新组装Cookie头(避免解析后丢失其他Cookie)
        set req.http.cookie = cookie.get_string();
    }

    # 逻辑1:没有语言Cookie,且当前URL语言不是默认语言 → 重定向到默认语言路径
    if (req.http.localeCookie == "" && req.http.locale != req.http.default_locale) {
        set req.http.X-Redirect-Url = req.http.path_without_locale;
        return (synth(302));
    }

    # 逻辑2:有语言Cookie,但当前URL语言和Cookie不一致 → 重定向到Cookie指定的语言路径
    if (req.http.localeCookie != "" && req.http.locale != req.http.localeCookie) {
        # 如果Cookie是默认语言,重定向到不带前缀的路径;否则加上语言前缀
        if (req.http.localeCookie == req.http.default_locale) {
            set req.http.X-Redirect-Url = req.http.path_without_locale;
        } else {
            set req.http.X-Redirect-Url = "/" + req.http.localeCookie + req.http.path_without_locale;
        }
        return (synth(302));
    }

    # 其他情况正常缓存/透传
    return (hash);
}

sub vcl_synth {
    # 处理302重定向,设置Location响应头
    if (resp.status == 302 && req.http.X-Redirect-Url) {
        set resp.http.Location = req.http.X-Redirect-Url;
        set resp.status = 302;
        set resp.reason = "Found";
        return (deliver);
    }
}

关键逻辑说明

  • 路径跳过规则:修正了你原配置中的正则错误(去掉了文件后缀匹配里多余的斜杠),确保API、静态资源和静态文件不会被重定向逻辑干扰。
  • 语言提取逻辑:区分了带语言前缀的URL和默认语言的无前缀URL,同时提取了去掉语言前缀的纯路径部分,方便后续重定向拼接。
  • Cookie处理:解析Cookie时保留了其他Cookie的完整性,避免影响站点其他依赖Cookie的功能。
  • 重定向分支:完全对齐了你原Next.js中间件的两个核心规则:
    1. 无Cookie时强制跳转到默认语言路径
    2. Cookie语言与当前URL语言不一致时,跳转到Cookie指定的语言路径(默认语言保持无前缀)

注意事项

  • 记得把req.http.default_locale的值改成你站点实际的默认语言(比如"zh-CN"如果是中文默认)
  • 测试时可以用浏览器的开发者工具查看Cookie和重定向行为,确保逻辑符合预期
  • 如果你的语言码是两位以上(比如"zh-CN"),需要修改语言提取的正则(把^/[a-z]{2}/改成^/[a-z]{2}-[A-Z]{2}/之类的,根据实际格式调整)

备注:内容来源于stack exchange,提问作者Predaytor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:04:51