避免从Special:Random中使用缓存进行重定向

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了避免从Special:Random中使用缓存进行重定向相关的知识,希望对你有一定的参考价值。

我正在使用清漆将MediaWiki安装中的内容提供给用户。几乎每个页面都按照vcl中的定义正确缓存:

vcl 4.0;

backend default 
    .host = "xxxx";
    .port = "xxxx";


backend thumbor 
    .host = "xxxx";
    .port = "xxxx";


acl purge 
    "xxxx";


sub vcl_recv 
        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        set req.backend_hint= default;

        if (req.method == "PURGE") 
            if (!client.ip ~ purge) 
                return (synth(405, "Not allowed."));
             else 
                return (purge);
            
        

        if (req.method != "GET" && req.method != "HEAD" &&
            req.method != "PUT" && req.method != "POST" &&
            req.method != "TRACE" && req.method != "OPTIONS" &&
            req.method != "DELETE") 
                return (pipe);
        

        if (req.method != "GET" && req.method != "HEAD") 
            return (pass);
        

    if (req.http.If-None-Match) 
        return (pass);
    

    if (req.http.X-Debug-Server) 
        return (pass);
    

    if (req.http.Cache-Control ~ "no-cache") 
        ban(req.url);
    

        if (req.http.Accept-Encoding) 
          if (req.http.User-Agent ~ "MSIE 6") 
            unset req.http.Accept-Encoding;
           elsif (req.http.Accept-Encoding ~ "gzip") 
            set req.http.Accept-Encoding = "gzip";
           elsif (req.http.Accept-Encoding ~ "deflate") 
            set req.http.Accept-Encoding = "deflate";
           else 
            unset req.http.Accept-Encoding;
          
        

    if (req.url ~ "(?i)\.(jpg|jpeg|jpe|png)$" && req.url ~ "(?i)/thumb/" && req.http.Accept ~ "(?i)image/webp" && req.http.x-no-thumbor != "yes") 
        set req.http.x-orig-url = req.url;
        set req.url = regsub(req.url,".*\/thumb\/(.*)","/unsafe/filters:format(webp)/thumb/\1");
        set req.backend_hint = thumbor;
    

    if (req.url ~ "action=amp$") 
        unset req.http.Cookie;
        unset req.http.x-wap;
        return (hash);
    

        if (req.http.Authorization || req.http.Cookie ~ "session" || req.http.Cookie ~ "Token") 
            return (pass);
        

    if (req.http.Cookie ~ "droidwikiwikicookiewarning_dismissed=true") 
        set req.http.Cookie = "droidwikiwikicookiewarning_dismissed=true";
     else 
        unset req.http.Cookie;
    

    unset req.http.x-wap;
    if (req.http.User-Agent ~ "(?i)^(lg-|sie-|nec-|lge-|sgh-|pg-)|(mobi|240x240|240x320|320x320|alcatel|android|audiovox|bada|benq|blackberry|cdm-|compal-|docomo|ericsson|hiptop|htc[-_]|huawei|ipod|kddi-|kindle|meego|midp|mitsu|mmp\/|mot-|motor|ngm_|nintendo|opera.m|palm|panasonic|philips|phone|playstation|portalmmm|sagem-|samsung|sanyo|sec-|sendo|sharp|softbank|symbian|teleca|up.browser|webos)" && req.url !~ "(\?|&)(action=amp)") 
        set req.http.x-wap = "no";
    

    if (req.http.Cookie ~ "mf_useformat=") 
        set req.http.x-wap = "no";
    

        return (hash);


sub vcl_hash 
    hash_data(req.http.x-wap);


sub vcl_pipe 
        set req.http.connection = "close";


sub vcl_purge 
    if (req.url !~ "(\?|&)(action=amp)") 
        set req.http.X-Original = req.url;
        if (req.url ~ "&") 
            set req.url = req.url + "&action=amp";
         else 
            set req.url = req.url + "?action=amp";
        
        return (restart);
    

    if (req.http.X-Original) 
        set req.url = req.http.X-Original;
    

    if (!req.http.x-wap) 
        set req.http.x-wap = "no";
        return (restart);
    


sub vcl_hit 
        if (req.method == "PURGE") 
            ban(req.url);
            return (synth(200, "Purged"));
        

        if (!obj.ttl > 0s) 
            return (pass);
        


sub vcl_miss 
        if (req.method == "PURGE")  
            return (synth(200, "Not in cache"));
        


sub vcl_deliver 
    if (resp.http.x-origin == "thumbor" && resp.status != 200) 
        set req.url = req.http.x-orig-url;
        set req.http.x-no-thumbor = "yes";
        return (restart);
    

    if (obj.hits > 0) 
        set resp.http.X-Cache = "HIT";
     else 
        set resp.http.X-Cache = "MISS";
    


sub vcl_backend_error 
    set beresp.http.x-origin = beresp.backend.name;


sub vcl_backend_response 
        set beresp.grace = 120s;

        if (beresp.ttl < 48h) 
          set beresp.ttl = 48h;
               

        if (!beresp.ttl > 0s) 
          set beresp.uncacheable = true;
          return (deliver);
        

        if (beresp.http.Set-Cookie) 
          set beresp.uncacheable = true;
          return (deliver);
        

        if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") 
          set beresp.uncacheable = true;
          return (deliver);
        

        return (deliver);

但是,当前配置也会导致重定向被缓存。虽然这是通常的重定向页面(如文章A重定向到文章B)的完全预期的行为,但对于Special:Random页面而言,这是意外的。每次打开该页面时,该页面均会将我定向到一个随机页面。但是,由于重定向是由清漆缓存的,所以我总是被重定向到同一页面。

我已经想过:1.根本不缓存302重定向,但是,这可能会对其他重定向产生负面影响,我通常希望将其缓存2.但是,在Special:Random上有一个URL过滤器,为此,我需要对Wiki支持的所有语言进行此免除,以使其可靠。我对此不太满意

我现在的问题是:没有人知道如何可以通过规则来实现这一目标,该规则不需要维护,并且只涉及Special:Random?也许是解决方案,Wikimedia Wiki也使用该解决方案吗?在那里,Special:Random页面始终重定向到另一个页面,但是,我无法在其代码存储库中找到实现该功能的代码块:(

答案

Varnish尊重可以从您的应用程序发送的常规Cache-Control HTTP响应标头。

我不是MediaWiki专家,但我注意到MediaWiki provides hooks扩展了它的行为。如果您可以加入MediaWiki的请求/响应流并检测到Special:Random情况,则可以注入Cache-Control: private, no-cache, no-store标头,以强制Varnish不缓存这些页面。

这是获得预期结果的理想方法,而无需编写VCL。

通常,优良作法是利用HTTP的缓存标头来控制反向缓存代理(例如Varnish)的行为。

  • 它使应用程序更易于移植
  • 它使应用程序减少对特定缓存技术的依赖
  • 它使开发人员能够从应用程序的体系结构中考虑缓存

以上是关于避免从Special:Random中使用缓存进行重定向的主要内容,如果未能解决你的问题,请参考以下文章

避免js缓存

如何进行网站性能优化

如何进行网站性能优化

如何进行网站性能优化

Falcor:避免过时的客户端缓存

301 和 301 http 重定向是不是可以使用 expires 标头进行缓存?