Language agnostic 如何知道何时发送304 Not Modified响应

Language agnostic 如何知道何时发送304 Not Modified响应,language-agnostic,http,Language Agnostic,Http,我正在编写一种资源处理方法,在这种方法中,我控制对各种文件的访问,并希望能够利用浏览器的缓存。我的问题有两个方面: 为了确定是否应该发送304响应,我需要检查哪些最终HTTP头,以及检查它们时我在寻找什么 此外,当我最初以200响应的形式发送文件(如“Last Modified”)时,是否需要发送任何头文件 一些psuedo代码可能是最有用的答案 缓存控制头呢?各种可能的值是否会影响您发送给客户机的内容(即最大年龄),或者仅在遵循修改后才应发送?如果客户机明确声明其缓存中可能已经有页面,则应发

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

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

  • 此外,当我最初以200响应的形式发送文件(如“Last Modified”)时,是否需要发送任何头文件

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



    缓存控制头呢?各种可能的值是否会影响您发送给客户机的内容(即最大年龄),或者仅在遵循修改后才应发送?

    如果客户机明确声明其缓存中可能已经有页面,则应发送304。这称为条件GET,它应该包括请求中修改后的,因为

    基本上,这个请求头包含一个日期,客户机声明从该日期起拥有一个缓存副本。您应该检查内容在此日期之后是否有更改,如果没有更改,请发送304


    请参阅RFC中的相关部分。

    以下是我如何实现它的。这段代码已经使用了一年多,并且使用了多种浏览器,所以我认为它非常可靠。这是基于并通过观察各种浏览器发送的内容和时间

    以下是伪代码:

    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 此文件(myfile)的服务器\u etag=gen\u etag\u etag_from_browser=获取标题(“etag”) 如果浏览器中的etag_不存在: etag_from_browser=获取_标题(“如果不匹配”) 如果浏览器引用了etag: 去掉引号(例如“foo”-->foo) 将服务器设置为http头 如果浏览器中的etag\u与服务器匹配 向浏览器发送304返回代码 下面是我的服务器逻辑的一个片段,可以处理这个问题

    /* 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或如果没有匹配项*/ /*有些客户会引用parm,如果是,则会引用strip*/ mketag(etag和sb); etagin=apr_table_get(r->headers_in,“Etag”); if(etagin==NULL) etagin=apr_table_get(r->headers_in,“如果没有匹配”); 如果(etag!=NULL&&etag[0]='''''”){ int sl; sl=斯特伦(etag); memmove(etag、etag+1、sl+1); etag[sl-2]=0; logit(2,“etag=:%s:”,etag); } ... apr\u table\u add(r->headers\u out,“ETag”,ETag); ... if(etagin!=NULL&&strcmp(etagin,etag)==0){ /*如果etag匹配,我们将返回304*/ rc=HTTP\u未修改; }
    如果您需要etag生成方面的帮助,请发布另一个问题,我将挖掘出一些代码。HTH!

    关于缓存控制:


    在提供服务时,您不必担心缓存控件,只需将其设置为合理的值。它基本上是告诉浏览器和其他下游实体(如代理)超时缓存之前应经过的最长时间。

    304 Not Modified(304未修改)响应可能由GET或HEAD请求产生,该请求具有If Modified Since(“IMS”)或If Not Match(“INM”)标头

    为了决定在收到这些标头时要做什么,假设您在处理GET请求时没有这些条件标头。确定ETag和上次修改的标头的值将在该响应中,并使用它们来做出决定。希望您已经构建了您的系统,以便确定这一点不太困难而不是构建完整的响应

    如果有一个INM,并且该头的值与您将放置在ETag中的值相同,则使用304进行响应

    如果存在IMS,且该标题中的日期值晚于您将在上次修改的标题中放置的日期值,则使用304进行响应

    否则,继续操作,就像请求不包含这些头一样

    对于问题的第2部分,请找出哪些(Expires、ETag和Last Modified)头可以轻松、正确地在Web应用程序中生成

    建议阅读材料:


    我们也在处理缓存但安全的资源。如果您发送/生成ETAg头(RFC 2616第13.3节建议您应该这样做),则客户端必须在条件请求中使用它(通常在If None Match-HTTP\u If\u None\u Match-header中)。如果您发送上次修改的头(同样,您应该这样做),然后您应该检查If Modified Since-HTTP_If_Modified_Since-头。如果您同时发送这两个头,那么客户端应该同时发送这两个头,但它必须发送ETag。还要注意,validtion只是定义为检查条件头是否与要发送的头严格相等。此外,只有强验证器(如ETag)将用于范围请求(仅请求部分资源)

    实际上,由于我们保护的资源是相当静态的,一秒钟的延迟时间是可以接受的,因此我们正在执行以下操作:

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

    如果没有,请重定向它们或发送一个4xx响应(视情况而定)。我们将生成404个响应,以响应看起来像黑客企图或公然尝试执行安全终止运行的请求

  • 将If-Modified-Since标头与我们将发送的上次修改的标头(见下文)进行比较,以确保严格相等

    如果匹配,则发送304 Not Modified响应并退出页面处理

  • 使用请求资源的修改时间创建上次修改的标头

    在RFC2616中查找HTTP日期格式

  • 发送标题和资源内容以及适当的内容类型

  • 我们决定避免使用ETag头,因为它对于我们来说是多余的。我想我们也可以使用日期时间戳作为ETag。如果我们使用真正的ETag系统,我们将