1、直接在.aspx页面中设置
最直接的,在.aspx页面中添加一行如下代码:

<%@ OutputCache Duration="3600" VaryByParam="None" %>

表示将这个页面缓存1小时。运行页面查看请求头信息:
第一次运行,效果如图:

再次请求页面
点击“转到”或者光标移入地址栏然后回车,或者F5刷新页面,效果如图:

注意:缓存对ctrl+F5强刷不起作用。

可以看到,设置后请求响应头中多了max-age、Expires、Last-Modified这三个属性,并且Http状态码也由200变成了304,说明我们成功设置了该页面的缓存。
对比两次请求头里的Cache-Control,发现第一次是no-cache,第二次是max-age=0,并且第三、第四。。次都是max-age=0,关于Cache-Control值的说明如下:
如果no-cache出现在请求中,则代表浏览器要求服务器,此次请求必须重新返回最新文件(请求完成后,你会看到http状态码是200);如果max-age=0出现在响应中,则代表服务器要求浏览器你在使用本地缓存的时候,必须先和服务器进行一遍通信,将etag、 If-Not-Modified等字段传递给服务器以便验证当前浏览器端使用的文件是否是最新的(如果浏览器用的是最新的文件,http状态码返回304,服务器告诉浏览器使用本地缓存即可;否则返回200,浏览器得自己吧文件重新下载一遍)。

请求页面方式说明:

首次请求 返回状态码200,显然得到全部正文。
F5 刷新,对Last-Modified有效,它是让服务器判断是否需要读取缓存,所以,依然存在请求和返回数据。状态码是304。
点击“转到”或者光标移入地址栏然后回车 对Cache-Control有效,是浏览器自己决定是否读取缓存,如果在缓存期限内,浏览器不会向WEB服务器发送请求,我们可以看到send和receive的数据全部是0。无交互,故无状态码。
ctrl+f5 相当于是强制刷新,所以状态码200 OK,返回全部正文数据。

2、在.cs代码中设置

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace HttpTest
{
public partial class HttpTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
int intHttpCacheMaxAge = 0; //浏览器缓存时间,单位:秒
string strHttpCacheMaxAge = ConfigurationManager.AppSettings["httpCacheMaxAge"];
if (!string.IsNullOrEmpty(strHttpCacheMaxAge))
{
intHttpCacheMaxAge = Convert.ToInt32(strHttpCacheMaxAge);
} //设置缓存过期变量,默认为缓存时间多1秒,即第一次请求总让它返回200
int seconds = intHttpCacheMaxAge + 1;
DateTime? IfModifiedSince = null;
if (!string.IsNullOrEmpty(Request.Headers["If-Modified-Since"]))
{
IfModifiedSince = Convert.ToDateTime(Request.Headers["If-Modified-Since"]);
seconds = (DateTime.Now - Convert.ToDateTime(IfModifiedSince)).Seconds;
}
if (seconds > intHttpCacheMaxAge)
{
Common.Common.currDateTime = DateTime.Now;
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetExpires(Convert.ToDateTime(Common.Common.currDateTime).AddSeconds(intHttpCacheMaxAge));
Response.Cache.SetLastModified(Convert.ToDateTime(Common.Common.currDateTime));
}
else
{
Response.Status = "304 Not Modified..";
Response.StatusCode = 304;
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetExpires(Convert.ToDateTime(Common.Common.currDateTime).AddSeconds(intHttpCacheMaxAge));
Response.Cache.SetLastModified(Convert.ToDateTime(Common.Common.currDateTime));
////上面设置了响应请求状态为304后,我们不希望再继续执行其他的业务逻辑了,所以,
////要阻止后续代码的执行,有以下两种方法:
////方法一:使用CompleteRequest()方法直接执行EndRequest事件,如:
//HttpApplication app = (HttpApplication)sender;
//app.CompleteRequest();
////方法二:使用return跳出代码执行,不执行return后面的任何代码,如:
return;
}
}
catch (Exception ex)
{
Response.Write("异常!" + ex);
}
}
}
}

配置文件:

 <!--设置浏览器缓存时间,单位:秒-->
<add key="httpCacheMaxAge" value="10"/>

这种方法可以针对单个页面设置,比较灵活。

3、利用HttpModule和HttpWorkerRequest设置
相比前两种,这种方法效率高些。
为了利用HttpModule,所以我们先要创建一个实现了IHttpModule接口的类,如:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web; namespace HttpTest.Module
{
public class HttpCacheModule:IHttpModule
{
public void Init(HttpApplication context)
{
context.EndRequest += context_EndRequest;
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
IServiceProvider provider = (IServiceProvider)app.Context;
HttpWorkerRequest worker = (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest)); int intHttpCacheMaxAge = 0; //浏览器缓存时间,单位:秒
string strHttpCacheMaxAge = ConfigurationManager.AppSettings["httpCacheMaxAge"];
if (!string.IsNullOrEmpty(strHttpCacheMaxAge))
{
intHttpCacheMaxAge = Convert.ToInt32(strHttpCacheMaxAge);
}
//设置缓存过期变量,默认为缓存时间多1秒,即第一次请求总让它返回200
int seconds = intHttpCacheMaxAge+1;
DateTime? IfModifiedSince = null;
if (app.Context.Request.Headers["If-Modified-Since"]!=null)
{
IfModifiedSince = Convert.ToDateTime(app.Context.Request.Headers["If-Modified-Since"]);
seconds = (DateTime.Now - Convert.ToDateTime(IfModifiedSince)).Seconds;
}
if (seconds > intHttpCacheMaxAge)
{
Common.Common.currDateTime = DateTime.Now;
}
else
{
app.Context.Response.Status = "304 Not Modified..";
app.Context.Response.StatusCode = 304;
}
worker.SendKnownResponseHeader(HttpWorkerRequest.HeaderCacheControl, "public");
worker.SendKnownResponseHeader(HttpWorkerRequest.HeaderExpires, Convert.ToDateTime(Common.Common.currDateTime).AddSeconds(intHttpCacheMaxAge).ToUniversalTime().ToString("r"));
worker.SendKnownResponseHeader(HttpWorkerRequest.HeaderLastModified, Convert.ToDateTime(Common.Common.currDateTime).ToUniversalTime().ToString("r"));
} public void Dispose()
{
} }
}

配置文件:

IIS6中按以下配置:
<system.web>
<httpModules>
<add name="HttpCacheModule" type="HttpTest.Module.HttpCacheModule,HttpTest"/>
</httpModules>
</system.web>
IIS7及后续版中本:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="HttpCacheModule" type="HttpTest.Module.HttpCacheModule,HttpTest"/>
</modules>
</system.webServer>

另外,为了保存当前时间做缓存过期判断,所以定义一个静态变量,如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace HttpTest.Common
{
public static class Common
{
public static DateTime? currDateTime = null;
}
}

并且在Global文件的Application_Start方法中初始化它,如:

void Application_Start(object sender, EventArgs e)
{
Common.Common.currDateTime = DateTime.Now;
}

这种方式适合对所有页面都有效,适合批量设置。

参考资料:
https://www.cnblogs.com/fish-li/archive/2012/01/11/2320027.html
https://segmentfault.com/q/1010000002578217
https://www.cnblogs.com/ajunForNet/archive/2012/05/19/2509232.html
https://www.cnblogs.com/futan/archive/2013/04/21/cachehuancun.html
https://www.cnblogs.com/yuanyuan/p/4921717.html(HttpModule详解)
http://www.cnblogs.com/yuanyuan/archive/2010/11/15/1877709.html
http://www.cnblogs.com/luminji/archive/2011/09/14/2174751.html
http://www.cnblogs.com/luminji/archive/2011/09/13/2172737.html

Http请求头缓存设置方法的更多相关文章

  1. http请求头缓存实现

    转自CSDN ouyang-web之路 原文链接:https://blog.csdn.net/cangqiong_xiamen/article/details/90405555 一.浏览器的缓存 st ...

  2. AngularJS 中设置 AJAX get 请求不缓存的方法

    var app = angular.module('manager', ['ngRoute']); app.config(['$routeProvider', function($routeProvi ...

  3. ASP.NET MSSQL 依赖缓存设置方法

    更多的时候,我们的服务器性能损耗还是在查询数据库的时候,所以对数据库的缓存还是显得特别重要,上面几种方式都可以实现部分数据缓存功能.但问题是我们的数据有时候是在变化的,这样用户可能在缓存期间查询的数据 ...

  4. node响应头缓存设置

    我把react项目分成4个板块,在路由的顶层 今天在手机上打开react项目的时候,发现平级路由跳转时某一个图片较多的板块图片总是渲染得很慢,这分明是重新发起请求了. 然后我先查一下react-rou ...

  5. 网络请求 post 的接受请求头的代理方法

    接收响应头 content-Length content-Type - (void)connection:(NSURLConnection *)connection didReceiveRespons ...

  6. jsonwebapi请求头的设置

    Content-Type: application/x-www-form-urlencoded; charset=UTF-8

  7. 接口测试——HttpClient工具的https请求、代理设置、请求头设置、获取状态码和响应头

    目录 https请求 代理设置 请求头设置 获取状态码 接收响应头 https请求 https协议(Secure Hypertext Transfer Protocol) : 安全超文本传输协议, H ...

  8. 给RabbitMQ发送消息时,设置请求头Header。

    消费者的请求头 生产者设置请求头 由于消费者那里,@Payload是接受的消息体,使用了@Header注解,需要请求头,生产者这边就要设置请求头,然后rabbitTemplate再调用convertA ...

  9. HttpWebRequest 改为 HttpClient 踩坑记-请求头设置

    HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...

随机推荐

  1. python 字符串(str)和列表(list)的互相转换

    1.str to list  str1 = "12345"list1 = list(str1)print list1 str2 = "123 sjhid dhi" ...

  2. PIMPL(private implementantion)模式(转载)

    前记:请搜索PIMPL(private implementantion)模式和桥接模式, PIMPL是桥接模式的一种典型实现 以下转自:http://blog.csdn.net/nrc_douning ...

  3. 华为鸿蒙OS能取代安卓吗?

    先回答问题,不能,起码几年之内不存在这种可能.8月9日华为的开发者大会上,余承东说:鸿蒙是一款基于微内核的全场景分布式OS.鸿蒙OS的设计初衷是为满足全场景智慧体验的高标准的连接要求,为此华为提出了4 ...

  4. Mac 卸载mysql

    sudo rm /usr/local/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf /Library/StartupItems/MySQLCOM su ...

  5. Android四层体系架构

    Application应用层 应用是用Java语言编写的运行在虚拟机上的程序,即图中最上层的蓝色部分.手机的上层应用其实,Google最开始时就在Android系统中捆绑了一些核心应用比如e-mail ...

  6. numpy基本方法总结

    NumPy基本方法 一.数组方法 创建数组:arange()创建一维数组:array()创建一维或多维数组,其参数是类似于数组的对象,如列表等 读取数组元素:如a[0],a[0,0] 数组变形:如b= ...

  7. python之scrapy的debug、shell、settings、pipelines

    1.debug了解 2.scrapy shell了解 Scrapy shell是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath表达式 使用方法: scrap ...

  8. RDD的cache 与 checkpoint 的区别

    问题:cache 与 checkpoint 的区别? 关于这个问题,Tathagata Das 有一段回答: There is a significant difference between cac ...

  9. 【转载】oracle中decode函数用法

    1.DECODE的语法:DECODE(value,if1,then1,if2,then2,if3,then3,...,else).表示假设value 等于if1时,DECODE函数的结果返回then1 ...

  10. Unity学习

    UnityAPI常用方法和类 Unity中的动画系统和Timeline (1) 普通动画创建 (2) 按钮动画和2D精灵动画 (3) 模型和动画导入 C#编程 (1) 委托 Lambda表达式和事件 ...