清漆:如何根据cookie更改网站的语言?

时间:2014-07-19 10:52:06

标签: cookies varnish varnish-vcl

我的网站几乎正常运作。它适用于一种语言,但我有一个设置语言的cookie。我也把它拆了。

问题是我无法改变我的cookie的价值,我无法知道如何做到这一点。 我的网站收到一个名为" lg = 1"的变量。在哪里" 1"是语言代码。

我不知道如何将其传递到我的网站,以获得"英语"版本并再次保存新的cookie(lg = 1值),因此下次用户访问时不使用lg = 1变量,他会根据cookie值访问我们的英文网站。

有人可以帮帮我吗? 谢谢你

3 个答案:

答案 0 :(得分:0)

如果您希望能够根据get-parameter设置cookie,您有两个选择

  1. 使用javascript设置Cookie。 Here is a SO answer for setting Cookie with JS
  2. 将Varnish配置为始终将包含“lg =”的请求传递给您的应用程序,以便您可以在那里设置cookie。

    sub vcl_recv {
        if (req.url ~ ".*lg=") {
            return (pass);
        }
    
        #Your other code in vcl_recv.....
    }
    

答案 1 :(得分:0)

你可能需要编辑你的VCL文件,默认情况下像/etc/varnish/default.vcl

当您收到语言参数时,您可以通过Varnish设置cookie。 然后使用cookie的值覆盖后端的请求URL。

应该是这样的:

sub vcl_recv {
  // Use the value of the cookie to override the request url.
  if (req.http.Cookie ~ "lg") {
    set req.url = req.url + "?" + req.http.Cookie;
  }

  // Go to VCL_error to redirect and remove the parametter.
  if (req.url ~ "(?i)lg=1") {
    error 802 "Remember to use the english version";
  }
}


sub vcl_error {
  /* Removes lg parameter and remember the english choice */
  if (obj.status == 802) {
    set obj.http.Set-Cookie = "lg=1; domain=." + req.http.host + "; path=/";
    set obj.http.Location = req.http.X-Forwarded-Proto + "://" + req.http.host + regsub(req.url, "\?lg=1", "");
    set obj.status = 302;
    return(deliver);
  }
}

我更愿意为每种语言使用不同的子域,就像您在收到参数时可以将用户重定向到子域一样。通过这样做,您不需要每次都覆盖request.url。

答案 2 :(得分:0)

我将使用以下方法来实现:

  1. 检查 lg cookie是否存在。如果不存在,则使用后端服务器或清漆服务器进行设置。
  2. 我更喜欢使用varnish而不是后端服务器设置语言cookie,以避免后端服务器上的过多请求/加载。
  3. 默认语言选择必须是英语,即" 1"
  4. 根据用户语言选择设置哈希。它将有助于根据语言维护不同的缓存,也可以从缓存中检索数据。

    请参考以下代码:

    我使用了 IPD Cookie。

    backend default {
        #applicable code goes here
    }
    sub identify_cookie{
        #Call cookie based detection method in vcl_recv
        if (req.http.cookie ~ "IPD=") {
                set req.http.Language = regsub(req.http.cookie, "(.*?)(IPD=)([^;]*)(.*)$", "\3");
        }
    }
    
    C{
        #used to set persistent(9+ years) cookie from varnish server.
        const char*  persistent_cookie(char *cookie_name){             
                time_t rawtime;
                struct tm *info;
                char c_time_string[80];
    
                rawtime = time(NULL) * 1.2; /*Added 9 years*/;
                info = localtime(&rawtime);
                strftime(c_time_string,80,"%a, %d-%b-%Y %H:%M:%S %Z", info);
    
                char * new_str ;
                if((new_str = malloc(strlen(cookie_name)+strlen(c_time_string)+1)) != NULL){
                        new_str[0] = '\0';   // ensures the memory is an empty string
                        strcat(new_str,cookie_name);
                        strcat(new_str,c_time_string);
    
                } else {
                        syslog(LOG_INFO,"Persistent cookie malloc failed!\n");
                }
                return new_str;
        }
    }C
    
    sub vcl_recv {
       call identify_cookie; #Used to get identify cookie and get its value
       if(!req.http.Cookie ~ "IPD"){
                C{
                        VRT_SetHdr(sp, HDR_REQ, "\006X-IPD:",persistent_cookie("IPD=1; domain=yourdomain.com; path=/; Expires="),vrt_magic_string_end);
                }C
       }
    }
    sub vcl_fetch {
       set beresp.http.Set-Cookie = req.http.X-IPD; #used for debug purpose only.Check cookie in response header
    }
    sub vcl_backend_response {
        #applicable code goes here
    }
    
    sub vcl_deliver {
        #applicable code goes here
        set resp.http.X-Cookie = "Cookies Set ("req.http.X-IPD")"; #used for debug purpose only.Check cookie in response header
    }
    sub vcl_error {
        #applicable code goes here
    }
    sub vcl_hash {
        hash_data(req.url);
        if (req.http.host) {
            hash_data(req.http.host);
        }
        if(!req.http.Language){
            req.http.Language = 1 #default english language
        }
        hash_data(req.http.Language); # make different hash for different language to avoid cache clashing
        return(hash);    
    }
    sub vcl_pipe {
        #applicable code goes here
    }
    sub vcl_pass {
        #applicable code goes here
    }
    

    注意:请确保仅更改Cookie名称。规则表达式支持从多个Cookie中检索Cookie值而不考虑其订单