首页 / 知识

关于不可知的语言:如何知道何时发送304 Not Modified响应

2023-04-11 19:31:00

关于不可知的语言:如何知道何时发送304 Not Modified响应

How to know when to send a 304 Not Modified response

我正在编写一种资源处理方法,该方法可以控制对各种文件的访问,并且希望能够利用浏览器的缓存。我的问题有两个:

  • 为了确定是否应该发送304响应,我需要检查哪些最终的HTTP标头?在检查它们时我在寻找什么?

  • 此外,当我最初以200响应发送文件(例如" Last-Modified")时,是否还需要发送任何标头?

  • 一些伪代码可能是最有用的答案。

    缓存控制标头如何?

    可能的各种可能值会影响您发送给客户端的内容(即最大年龄)还是仅在遵守修改后的条件下才可以?


    这是我实施的方式。该代码已经使用了多个浏览器,已经运行了一年多,所以我认为它非常可靠。这基于RFC 2616并观察各种浏览器发送的内容和时间。

    这是伪代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    server_etag = gen_etag_for_this_file(myfile)
    etag_from_browser = get_header("Etag")

    if etag_from_browser does not exist:
        etag_from_browser = get_header("If-None-Match")
    if the browser has quoted the etag:
        strip the quotes (e.g."foo" --> foo)

    set server_etag into http header

    if etag_from_browser matches server_etag
        send 304 return code to browser

    这是我的服务器逻辑的一个片段,用于处理此问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /* the client should set either Etag or If-None-Match */
    /* some clients quote the parm, strip quotes if so    */
    mketag(etag, &sb);

    etagin = apr_table_get(r->headers_in,"Etag");
    if (etagin == NULL)
        etagin = apr_table_get(r->headers_in,"If-None-Match");
    if (etag != NULL && etag[0] == '"') {
        int sl;
        sl = strlen(etag);
        memmove(etag, etag+1, sl+1);
        etag[sl-2] = 0;
        logit(2,"etag=:%s:",etag);
    }  
    ...
    apr_table_add(r->headers_out,"ETag", etag);
    ...
    if (etagin != NULL && strcmp(etagin, etag) == 0) {
        /* if the etag matches, we return a 304 */
        rc = HTTP_NOT_MODIFIED;
    }

    如果您需要有关etag生成的帮助,请发布另一个问题,我将挖掘出一些实现此目的的代码。 HTH!


    带有If-Modified-Since(" IMS")或If-Not-Match(" INM")标头的GET或HEAD请求可能会产生304 Not Modified响应。

    为了确定接收这些标头时的处理方式,请想象您正在处理没有这些条件标头的GET请求。确定该响应中ETag和Last-Modified标头的值是什么,并使用它们来做出决定。希望您已经建立了自己的系统,从而确定该系统比构造完整的响应所需的成本更低。

    如果有一个INM且该标头的值与您将在ETag中放置的值相同,则返回304。

    如果有一个IMS,并且该标头中的日期值晚于您在" Last-Modified"中放置的日期,则响应304。

    否则,就像请求中不包含那些标头一样进行操作。

    要以省力的方法处理问题的第2部分,请弄清楚可以在Web应用程序中轻松正确地生成哪些(Expires,ETag和Last-Modified)标头。

    建议的阅读材料:

    http://www.w3.org/Protocols/rfc2616/rfc2616.html

    http://www.mnot.net/cache_docs/


    如果客户端明确声明其缓存中可能已包含该页面,则应发送304。这称为条件GET,它应在请求中包含if-modified-since标头。

    基本上,此请求标头包含一个日期,客户端声称从该日期起具有缓存的副本。您应该检查此日期之后内容是否已更改,如果尚未更改,则发送304。

    有关RFC中的相关部分,请参见http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25。


    我们还在处理缓存但安全的资源。如果发送/生成ETAg标头(RFC 2616第13.3节建议您这样做),则客户端必须在条件请求中使用它(通常在If-None-Match-HTTP_IF_NONE_MATCH-标头中)。如果发送了Last-Modified头(再次应该),则应检查If-Modified-Since-HTTP_IF_MODIFIED_SINCE-头。如果同时发送了两者,则客户端应该发送两者,但是它必须发送ETag。还要注意,验证只是定义为检查条件标头与要发送的条件标头是否严格相等。另外,对于范围内的请求(仅请求资源的一部分),将仅使用强验证器(例如ETag)。

    在实践中,由于我们保护的资源是相当静态的,并且一秒的延迟时间是可以接受的,因此我们将执行以下操作:

  • ?检查用户是否有权访问所请求的资源

    ?? ?如果不是,请重定向它们或发送适当的4xx响应。我们将为请求发出404响应,这些请求看起来像是黑客尝试或公然尝试执行安全性最终运行。

  • ?将If-Modified-Since标头与我们为严格相等而发送的Last-Modified标头进行比较(见下文)

    ?? ?如果它们匹配,则发送" 304未修改"响应并退出页面处理

  • ?使用所请求资源的修改时间创建Last-Modified标头

    ??查找RFC 2616

    中的HTTP日期格式

  • ?发送标题和资源内容以及适当的Content-Type

  • 我们决定避开ETag标头,因为对于我们的目的而言,它太过分了。我想我们也可以只使用日期时间戳作为ETag。如果我们转向真正的ETag系统,我们可能会存储资源的计算得出的哈希值并将其用作ETag。

    如果从数据库内容中动态生成资源,则ETag可能更适合您的需求,因为它们只是您认为合适的文本。


    关于缓存控制:

    除了提供合理的值外,您不必担心分发时的缓存控制。基本上,这是告诉浏览器和其他下游实体(例如代理)在超时缓存之前应该经过的最长时间。


    响应语言文件处理方法

    最新内容

    相关内容

    热门文章

    推荐文章

    标签云

    猜你喜欢