• ASP.NET MVC中使用jQuery时的浏览器缓存问题


    介绍

    虽然jQuery在浏览器ajax调用的时候对缓存提供了非常好的支持,还是有必要了解一下怎样高效地使用http协议。

    首先要做的事情是在server端支持HTTP GET,定义不同的URL输出不同的数据(MVC里相应的就是action)。

    假设要使用同一个地址获取不同的数据,那就不正确了。一个HTTP POST也不行由于POST不能被缓存。很多开发者使用POST主要有2个原因:明白了数据不能被缓存,或者是避免JSON攻击(JSON返回数组的时候能够被入侵)。

    缓存解释

    jQuery全局对象里的ajax方法提供了一些options来支持缓存和Conditional GETs功能。

    $.ajax({
        ifModified: [true|false],
        cache: [true|false],
    });

    ifModified选项定义的是在ajax调用的时候是否支持Conditional GETs功能。jQuery会自己主动帮我们处理server端返回的名为Last-Modified的header值,然后在随后的请求里的header里发送If-Modified-Since。这须要我们的MVC Controller要实现Conditional GETs功能才干用。

    Conditional GETs功能在http缓存上下文中用于又一次验证缓存中过期的条目。假设jQuery觉得一个条目已经过期了,它首先会请求server使用Conditional GETs功能又一次验证该条目,假设server返回状态码304(Not modified),jQuery会又一次使用缓存里的该项目,这种话,我们能够节约非常多流量去下载页面内容。

    cache选项基本上是覆盖server端返回的http header里的全部关于缓存的设置,假设设置cache选项为false的话,jQuery会在请求的URL后面附件一个时间戳,以便区分之前的URL地址,这样没错请求的内容都是最新的,也就是说浏览器每次接收的都是新地址,自然返回的都是最新数据。

    让我们来看几个场景:

    server端响应里设置No-Cache

    server端为王。假设server端明白定义了response响应不能被缓存的话,jQuery也无能为力。ajax里的cache选项将被忽略。

    JS代码:

    $('#nocache').click(function () {
        $.ajax({
            url: '/Home/NoCache',
            ifModified: false,
            cache: true,
            success: function (data, status, xhr) {
                $('#content').html(data.count);
            }
        });
    });

    C#代码:

    public ActionResult NoCache()
    {
       // 禁用缓存
       Response.Cache.SetCacheability(HttpCacheability.NoCache);
       return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
    }

    server端响应里设置过期时间

    server端设置过期时间用于缓存数据。该条目在client将根据过期时间被缓存。

    JS代码:

    $('#expires').click(function () {
        $.ajax({
            url: '/Home/Expires',
            ifModified: false,
            cache: true,
            success: function (data, status, xhr) {
                $('#content').html(data.count);
            }
        });
    });

    C#代码:

    public ActionResult Expires()
    {
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
        return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
    }

    client从来不缓存数据

    client决定每次都要最新的数据(不能使用缓存),也就是说ajaxi里的cache选项设置为false。无论server端怎样定义,jQuery每次请求的URL地址都是唯一不同的,目的是每次都获取最新的内容。

    JS代码:

    $('#expires_nocache').click(function () {
        $.ajax({
            url: '/Home/Expires',
            ifModified: false,
            cache: false, // 这里是关键
            success: function (data, status, xhr) {
                $('#content').html(data.count);
            }
        });
    });

    C#代码:

    public ActionResult Expires()
    {
        // 无论server端怎么设置都没用
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
        return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
    }

    server端和client使用Conditional Gets功能验证缓存数据

    client将条目放在缓存里。在过期之后又一次验证。server端必须实现Conditional GET功能(使用ETags或者last modified的header)。

    JS代码:

    $('#expires_conditional').click(function () {
        $.ajax({
            url: '/Home/ExpiresWithConditional',
            ifModified: true, // 这里是关键
            cache: true,
            success: function (data, status, xhr) {
                $('#content').html(data.count);
            }
        });
    });

    C#代码:

    public ActionResult ExpiresWithConditional()
    {
        if (Request.Headers["If-Modified-Since"] != null && Count % 2 == 0)
        {
            return new HttpStatusCodeResult((int)HttpStatusCode.NotModified);
        }
    
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
        Response.Cache.SetLastModified(DateTime.Now);
    
        return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet);
    }

    上述MVC action中的代码仅仅是一个样例(非真实代码),在真实的实现中,server端应该可以知道数据自从上次响应以后是否被改动过。

    总结

    具体通过这4个场景,大家应该了解了ajax请求的缓存技术了吧,我就不做总结了。

  • 相关阅读:
    MVC4笔记 @functions @model @using
    NET平台4.0 发布网站流程及出错总结
    C#读写txt文件的方法
    jQuery Validate验证框架详解(转)
    用C#写的读写CSV文件
    devexpress 数据导入(gridcontrol 导出 csv)
    DevExpress XtraGrid 数据导出导入Excel
    DevExpress 表中数据导出
    DevExpress 重编译 替换强命名 修改源码
    Delphi 的运算符列表
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6786369.html
Copyright © 2020-2023  润新知