整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML禁止input,select等输入框页面缓存技巧

要:禁止input缓存,禁止select缓存

有时候,我们页面的输入框,我们再页面里输入内容后,并不保存,但是刷新页面会发现值为输入的页面,完全没有从新去从后台取值,这是怎么回事呢?如下:

雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆雷姆雷姆拉姆拉姆

<input type="text" value="">
<select>
<option value="1">1</option>
<option value="2">1</option>
</select>

其实多数浏览器默认会缓存input的值,只有使用ctl+F5强制刷新的才可以清除缓存记录。如果不想让浏览器缓存input的值,很简单,只需要价格属性即可:autocomplete=”off”

例如上面例子,改为如下就不会缓存啦:

<input type="text" autocomplete="off" value="">
<select autocomplete="off">
<option value="1">1</option>
<option value="2">1</option>
</select>

听说还有一种直接加在form表单里也可以,但是因为我已经很久没有用form表单提交数据啦,都是用ajax异步提交的,所以我就没有采取这种方法,也很简单的如下:

<form action="#" autocomplete="off">  
<input type="text" value/>  
</form>

当然,没试过不知道行不行,应该是没问题的!

者:kevinylzhao,腾讯音乐前端开发工程师

浏览器缓存策略对于前端开发同学来说不陌生,大家都有一定的了解,但如果没有系统的归纳总结,可能三言两语很难说明白,甚至说错,尤其在面试过程中感触颇深,很多候选人对这类基础知识竟然都是一知半解,说出几个概念就没了,所以重新归纳总结下,温故而知新。


Web 缓存介绍

  • Web 缓存是指一个 Web 资源(如 html 页面,图片,js,数据等)存在于 Web 服务器和客户端(浏览器)之间的副本。
  • 缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,如果是相同的 URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。

Web 缓存的好处

  • 减少网络延迟,加快页面打开速度
  • 减少网络带宽消耗
  • 降低服务器压力
  • ...

HTTP 的缓存机制

简化的流程如下

根据什么规则缓存

  1. 新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:
  • 含有完整的过期时间控制头信息(HTTP 协议报头),并且仍在有效期内;
  • 浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;
  1. 校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签 Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如果发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。

HTTP 缓存的两个阶段

浏览器缓存一般分为两类:强缓存(也称本地缓存)和协商缓存(也称弱缓存)。

本地缓存阶段

浏览器发送请求前,会先去缓存里查看是否命中强缓存,如果命中,则直接从缓存中读取资源,不会发送请求到服务器。否则,进入下一步。

协商缓存阶段

当强缓存没有命中时,浏览器一定会向服务器发起请求。服务器会根据 Request Header 中的一些字段来判断是否命中协商缓存。如果命中,服务器会返回 304 响应,但是不会携带任何响应实体,只是告诉浏览器可以直接从浏览器缓存中获取这个资源。如果本地缓存和协商缓存都没有命中,则从直接从服务器加载资源。

启用&关闭缓存

按照本地缓存阶段和协商缓存阶段分类:

  1. 使用 HTML Meta 标签    Web 开发者可以在 HTML 页面的节点中加入标签,如下:

上述代码的作用是告诉浏览器当前页面不被缓存,事实上这种禁用缓存的形式用处很有限:

a. 仅有 IE 才能识别这段 meta 标签含义,其它主流浏览器仅识别“Cache-Control: no-store”的 meta 标签。

b. 在 IE 中识别到该 meta 标签含义,并不一定会在请求字段加上 Pragma,但的确会让当前页面每次都发新请求(仅限页面,页面上的资源则不受影响)。

  1. 使用缓存有关的 HTTP 消息报头 这里需要了解 HTTP 的基础知识。一个 URI 的完整 HTTP 协议交互过程是由 HTTP 请求和 HTTP 响应组成的。有关 HTTP 详细内容可参考《Hypertext Transfer Protocol — HTTP/1.1》、《HTTP 权威指南》等。

在 HTTP 请求和响应的消息报头中,常见的与缓存有关的消息报头有:

上图中只是常用的消息报头,下面来看下不同字段之间的关系和区别:

  1. Cache-Control 与 Expires
  2. Cache-Control:HTTP1.1 提出的特性,为了弥补 Expires 缺陷加入的,提供了更精确细致的缓存功能。详细了解详细看几个常见的指令:_ max-age:功能和 Expires 类似,但是后面跟一个以“秒”为单位的相对时间,来供浏览器计算过期时间。_ no-cache:提供了过期验证机制。(在 Chrome 的 devtools 中勾选 Disable cache 选项,发送的请求会去掉 If-Modified-Since 这个 Header。同时设置 Cache-Control:no-cache Pragma:no-cache,每次请求均为 200)
    • no-store:表示当前请求资源禁用缓存;
    • public:表示缓存的版本可以被代理服务器或者其他中间服务器识别;
    • private:表示只有用户自己的浏览器能够进行缓存,公共的代理服务器不允许缓存。
  • Expires:HTTP1.0 的特性,标识该资源过期的时间点,它是一个绝对值,格林威治时间(Greenwich Mean Time, GMT),即在这个时间点之后,缓存的资源过期;优先级:Cache-Control 优先级高于 Expires,为了兼容,通常两个头部同时设置;浏览器默认行为:其实就算 Response Header 中沒有设置 Cache-Control 和 Expires,浏览器仍然会缓存某些资源,这是浏览器的默认行为,是为了提升性能进行的优化,每个浏览器的行为可能不一致,有些浏览器甚至没有这样的优化。
  1. Last-Modified 与 ETag
  2. Last-Modified(Response Header)与 If-Modified-Since(Request Header)是一对报文头,属于 http 1.0。If-Modified-Since 是一个请求首部字段,并且只能用在 GET 或者 HEAD 请求中。Last-Modified 是一个响应首部字段,包含服务器认定的资源作出修改的日期及时间。当带着 If-Modified-Since 头访问服务器请求资源时,服务器会检查 Last-Modified,如果 Last-Modified 的时间早于或等于 If-Modified-Since 则会返回一个不带主体的 304 响应,否则将重新返回资源。(注意:在 Chrome 的 devtools 中勾选 Disable cache 选项后,发送的请求会去掉 If-Modified-Since 这个 Header。)
  • ETag 与 If-None-Match 是一对报文头,属于 http 1.1。ETag 是一个响应首部字段,它是根据实体内容生成的一段 hash 字符串,标识资源的状态,由服务端产生。If-None-Match 是一个条件式的请求首部。如果请求资源时在请求首部加上这个字段,值为之前服务器端返回的资源上的 ETag,则当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的时候,服务器才会返回带有所请求资源实体的 200 响应,否则服务器会返回不带实体的 304 响应。
  • ETag 能解决什么问题?

a. Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在 1 秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度;

b. 某些文件也许会周期性的更改,但是它的内容并不改变(仅仅改变的修改时间),但 Last-Modified 却改变了,导致文件没法使用缓存;

c. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。

  • 优先级:ETag 优先级比 Last-Modified 高,同时存在时会以 ETag 为准。
缓存位置

浏览器可以在内存、硬盘中开辟一个空间用于保存请求资源副本。我们经常调试时在 DevTools Network 里看到 Memory Cache(內存缓存)和 Disk Cache(硬盘缓存),指的就是缓存所在的位置。请求一个资源时,会按照优先级(Service Worker -> Memory Cache -> Disk Cache -> Push Cache)依次查找缓存,如果命中则使用缓存,否则发起请求。这里先介绍 Memory Cache 和 Disk Cache。

200 from memory cache

表示不访问服务器,直接从内存中读取缓存。因为缓存的资源保存在内存中,所以读取速度较快,但是关闭进程后,缓存资源也会随之销毁,一般来说,系统不会给内存分配较大的容量,因此内存缓存一般用于存储较小文件。同时内存缓存在有时效性要求的场景下也很有用(比如浏览器的隐私模式)。

200 from disk cache

表示不访问服务器,直接从硬盘中读取缓存。与内存相比,硬盘的读取速度相对较慢,但硬盘缓存持续的时间更长,关闭进程之后,缓存的资源仍然存在。由于硬盘的容量较大,因此一般用于存储大文件。

下图可清晰看出差别:

200 from prefetch cache

在 preload 或 prefetch 的资源加载时,两者也是均存储在 http cache,当资源加载完成后,如果资源是可以被缓存的,那么其被存储在 http cache 中等待后续使用;如果资源不可被缓存,那么其在被使用前均存储在 memory cache。

CDN Cache

以腾讯 CDN 为例:X-Cache-Lookup:Hit From MemCache 表示命中 CDN 节点的内存;X-Cache-Lookup:Hit From Disktank 表示命中 CDN 节点的磁盘;X-Cache-Lookup:Hit From Upstream 表示没有命中 CDN。

整体流程

从上图能感受到整个流程,比如常见两种刷新场景:

  • 当 F5 刷新网页时,跳过强缓存,但是会检查协商缓存;
  • 当 Ctrl + F5 强制刷新页面时,直接从服务器加载,跳过强缓存和协商缓存

其他 Web 缓存策略

IndexDB

IndexedDB 就是浏览器提供的本地数据库,能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。

异步 API 方法调用完后会立即返回,而不会阻塞调用线程。要异步访问数据库,要调用 window 对象 indexedDB 属性的 open() 方法。该方法返回一个 IDBRequest 对象 (IDBOpenDBRequest);异步操作通过在 IDBRequest 对象上触发事件来和调用程序进行通信。

常用异步 API 如下:

在 16 年曾基于 IndexDB 做过一整套缓存策略,有不错的优化效果:

Service Worker

SW 从 2014 年提出的草案到现在已经发展很成熟了,基于 SW 做离线缓存,让用户能够进行离线体验,消息推送体验,离线缓存能力涉及到 Cache 和 CacheStorage 的概念,篇幅有限,不展开了。

LocalStorage

localStorage 属性允许你访问一个 Document 源(origin)的对象 Storage 用于存储当前源的数据,除非用户人为清除(调用 localStorage api 或者清除浏览器数据), 否则存储在 localStorage 的数据将被长期保留。

SessionStorage

sessionStorage 属性允许你访问一个 session Storage 对象,用于存储当前会话的数据,存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。

定义最优缓存策略

  • 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次获取和存储该内容。注意:URL 区分大小写!
  • 确定中继缓存可以缓存哪些资源:对所有用户的响应完全相同的资源很适合由 CDN 或其他中继缓存进行缓存;
  • 确定每个资源的最优缓存周期:不同的资源可能有不同的更新要求。审查并确定每个资源适合的 max-age;
  • 确定网站的最佳缓存层级:对 HTML 文档组合使用包含内容特征码的资源网址以及短时间或 no-cache 的生命周期,可以控制客户端获取更新的速度;
  • 更新最小化:有些资源的更新比其他资源频繁。如果资源的特定部分(例如 JS 函数或一组 CSS 样式)会经常更新,应考虑将其代码作为单独的文件提供。这样,每次获取更新时,剩余内容(例如不会频繁更新的库代码)可以从缓存中获取,确保下载的内容量最少;
  • 确保服务器配置或移除 ETag:因为 Etag 跟服务器配置有关,每台服务器的 Etag 都是不同的;
  • 善用 HTML5 的缓存机制:合理设计启用 LocalStorage、SessionStorage、IndexDB、SW 等存储,会给页面性能带来明显提升;
  • 结合 Native 的强大存储能力:善于利用客户端能力,定制合适的缓存机制,打造极致体验。

结语

通过了解浏览器各种缓存机制和存储能力特点,结合业务制定合适的缓存策略,善用缓存是基本功,可以用于时常审查负责的业务,可能就会发现个别业务并没有运用到位,共勉。

览器缓存对于前端一点都不陌生,最常见的就是,新版本上线了,测试却说这怎么还没有变化呢?使用 ctr + F5 强制刷新之后,立马就好了。或者清除浏览器缓存,按住ctr+shift+delete,弹出如图:

我们会发现目前浏览器缓存的图片和文件的大小。或者进入chrome://chrome-urls/找到chrome://cache/ 就可以看到所有缓存的地址列表。对于浏览器缓存,前端对它是又爱又恨,有时想保留,有时想禁掉,所以看看浏览器缓存到底是怎样的?

一、什么是浏览器缓存?

浏览器缓存就是浏览器根据 url 第一次访问网站之后,将网站的 html、css、js、图片等文件复制一份保留到浏览器中,当你二次访问这个 url 的网站时,如果网站没有明确表示有更新时,浏览器直接在缓存中查找内容,不会再次请求网页内容,只有网页明确表示有更新时,浏览器才会向服务器发起网路请求,再次下载网页。

如上图,百度首页就是使用了缓存机制,首次访问之后 web资源被缓存,在后面重复请求中,资源直接在缓存中读取,而不是向服务器请求资源。

二、为什么使用缓存?

2.1、为什么很多网站二次打开速度很快?

网页二次打开很快,主要原因是第一次加载页面过程中,缓存了部分耗时数据,这一现象,对于单页面应用开发非常明显。

上一篇文章《浏览器工作原理》中,浏览器工作流程介绍,输入网址回车以后浏览器向服务器发起服务之前,会现在浏览器缓存中查询是否有需要的文件?如果有则直接在缓存中获取文件,避免向服务器请求和下载文件,所以节省了一部分时间。

2.2、浏览器缓存优点

1、减少网络带宽消耗

对于网站运营者或者访问网页的用户,带宽就代表着 money ,过多的消耗带宽,我们服务器配置就得升级,使用浏览器缓存之后,就会减少网络流量,降低运营成本。

2、降低服务器压力

使用浏览器缓存之后,除第一次访问需要向服务器请求网站全部资源,后续访问可以重复使用浏览器本地缓存,减少对服务器的请求,间接降低服务器的压力,同时,搜索引擎的爬虫也会根据缓存过期机制降低抓取的频率,也可以降低服务器压力。

3、减少网络延迟,加快网页加载

浏览器缓存 web资源后,减少网络请求,可以更快速地获取到服务器返回数据,同时使用浏览器缓存内的文件比服务器获取快很多,所以网页加载速度明显快很多。

三、浏览器的缓存规则

对于浏览器端的缓存来讲,这些规则是在 http 协议和 meta 标签中定义的。分别从两个维度:新鲜度和校验值,规定浏览器是否可以直接使用缓存中的副本,还是直接从服务器获取最新资源。

3.1、新鲜度(过期):浏览器缓存的有效期,缓存必须满足以下两个条件,浏览器才会认为是最新的,可以直接使用。

  • 含有完整的过期时间控制头信息,并在有效期内。
  • 浏览器已经使用过这个副本,并且在会话中已经检查过新鲜度。

3.2、校验值(验证):服务器返回资源的时候,会在响应头信息中带上资源实体标签 Entity Tag,可以用来作为浏览器再次请求过程的校验标识,如果发现校验标识不匹配,说明资源已经被修改过或过期,浏览器需要重新请求资源。

四、如何控制缓存?

缓存规则可以设置在html的meta标签,也可以设置在http协议头内。

4.1、前端 html 中 meta 标签

在 html 页面中加入缓存设置,代码如下:

<meta http-equiv="Pragma" content="no-cache"  />
<!-- Pragma是http1.0版本中给客户端设定缓存方式之一 -->

上边代码,禁止浏览器缓存,浏览器每次访问网页都要去服务器请求。事实这种禁用缓存形式作用有限:

  • 只有IE浏览器才能标识这段 meta 的含义,其他主流浏览器仅认识 “Cache-Control:no-store” 的 meta 标签。
  • 在IE浏览器中,并不一定添加 pragma,但是会让当前网页每次都会向服务器发送请求。

4.2、HTTP协议头

http请求和响应头中,与缓存相关的常见类型:

规则

消息报头

值/示例

类型

作用

新鲜度

Pragma

no-cache

响应

告诉浏览器忽略资源的缓存副本,每次访问都需要去服务器拉取【http1.0中存在的字段,在http1.1已被抛弃,使用Cache-Control替代,但为了做http协议的向下兼容,很多网站依旧会带上这个字段】


Expires

Mon, 15 Aug 2016 03:56:47 GMT

响应

启用缓存和定义缓存时间。告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求【http1.0中存在的字段,该字段所定义的缓存时间是相对服务器上的时间而言的,如果客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了。在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代】


Cache-Control

no-cache

响应

告诉浏览器忽略资源的缓存副本,强制每次请求直接发送给服务器,拉取资源,但不是“不缓存”



no-store

响应

强制缓存在任何情况下都不要保留任何副本



max-age=[秒]

响应

指明缓存副本的有效时长,从请求时间开始到过期时间之间的秒数



public

响应

任何路径的缓存者(本地缓存、代理服务器),可以无条件的缓存该资源



private

响应

只针对单个用户或者实体(不同用户、窗口)缓存资源


Last-Modified

Mon, 15 Aug 2016 03:56:47 GMT

响应

告诉浏览器这个资源最后的修改时间。服务器将资源传递给客户端时,会将资源最后更改的时间以“Last-Modified: GMT”的形式加在实体首部上一起返回给客户端【只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间】


If-Modified-Since

Mon, 15 Aug 2016 03:56:47 GMT

请求

其值为上次响应头的Last-Modified值,再次向web服务器请求时带上头If-Modified-Since。web服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),包括更新Last-Modified的值,HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304(无需请求,节省浏览),告知浏览器继续使用所保存的cache

校验值

ETag

"fd56273325a2114818df4f29a628226d"

响应

告诉浏览器当前资源在服务器的唯一标识符(生成规则由服务器决定)


If-None-Match

"fd56273325a2114818df4f29a628226d"

请求

当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值)。web服务器收到请求后发现有头If-None-Match则与被请求资源的相应校验串进行比对,决定返回200或304

各种类型之间的关系和区别:

  • Cache-Control 与 Expires:它两作用一样,都表明当前资源的有效期,控制浏览器是取缓存还是直接向服务器获取,Cache-Control可以设置的更细致,如果同时设置,它的优先级高于Expires。
  • Last-Modified / ETag 与 Cache-Control / Expires:配置Last-Modified/ETag的情况下,浏览器再次访问URL的资源,还是会发送请求到服务器,询问文件是否已经修改,如果没有,服务器会给浏览器返回304,浏览器直接从本地缓存中取就好了,反之,服务器会直接向浏览器返回数据。Cache-Control / Expires 检测本地缓存是否还在有效期内,在有效期内,直接使用本地缓存,阻止发送请求。如果同时设置,Cache-Control / Expiress 优先级更高。一般情况下,两者配合使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销。
  • Last-Modified 与 ETag:ETag主要是为了解决Last-Modified比较难解决的问题:1、Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度。2、如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存。3、有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。ETag是服务器自动生成或开发者生成对应资源在服务器的唯一标识符,能够更加精准控制缓存。两者可以一起使用,服务器优先验证ETag,一致时,才会继续比对Last-Mofifed,才决定是否要返回304。

五、不能缓存的请求

并不是所有的请求都能被缓存,无法被缓存的有:

  • post 请求无法被缓存。
  • 需要根据cookie、认证信息等决定输入内容的动态请求不能被缓存。
  • http响应头中不包含Last-Modified/ETag,也不包含Cache-Control/Expiress的请求无法被缓存。
  • http信息头明确设置Cache-Control:no-cache,pragma:no-cache或Cache-Control:max-age=0浏览器不缓存时。