ajax 请求 的一些残念

本文是篇真正的随笔 是我在写一份前端优化ppt时  想到哪写到哪 产生的一份  罗里吧嗦的 东东...有点懒的整理 ...所以就发布到这个旮旯吧.

 

Ajax 优化 

 

一 . 给被请求资源设置有效的长远的 Expires 的同时设置一个相对短 且合理的 max-age值

比如  对某一文件  服务器的响应头 中应该包含

Expires: Tue, 01 Jun 2030 15:43:46 GMT 

Cache-Control:max-age=60

以及Last Modified头或 ETag头 的其中一个.

 

对于ie浏览器来说头两项 缺一不可 的原因在于

假如 对于某文件 即没有 Expires 又没有 max-age的话 那么 缓存文件就无 过期时间…一旦某缓存文件无过期时间 而 我们又去使用 xhr 对象对服务器请求 该文件. 则会导致 ie直接使用本地缓存文件给我们 而不会发起一个http 连接请求给服务器.

我们需要给动态文件使用独立的eTag算法或lastModified 算法 以便确定内容的及时更新 .原因在于ie浏览器 对于动态文件 如 aspx php等 一样会固执的缓存他们 并在 xhr对象请求时 不发起http请求 此处应根据不同情况差异  选择性 确保ie 缓存文件的Expires 时间 和max-age或干脆禁止 ie缓存文件. 

永远不要期待ie像firefox chrome safari 等浏览器那样 对于aspx php等动态文件类型. 在默认http头中没有Expires 和max-age 以及Last Modified 或ETag时.自作主张的缓存文件并在xhr请求时不发起http请求. 

补充:对于动态文件 如aspx  iis默认不会发送 Last Modified 或ETag头 即 iis认为 对于动态文件 应该总是输出新的内容给客户端. 所以 客户端对于 动态文件 也总是不会有 if Modified Since 和If None Match头  这就导致 浏览器 的xhr对象 对动态文件做请求 不可能出现304状态码 也就是说 一旦发起http请求 并成功返回数据那么只有 200 的可能 这很合理 但是ie的问题在于如上面所说 于其他浏览器的区别之处就 在于  默认 无epxires的情况下的处理差别. 好在 设置 Expires和 max-age 可以完善的解决这些问题 而不会产生浏览器差异. 

 

只使用Expires而不使用max-age 虽然没问题 但是 这里需要一个预期 即 我们首先要 预期 客户端 与服务器端 时间相差不是很离谱 但因为这个是无法保证的 所以 我们需要 用max-age来保证过期时间的准确性. 

但如果只有max-age ie浏览器 的xhr 对象发起的请求 仍然会有bug  他会导致 浏览器 直接放弃 本地cache而每次都发起请求 到服务器 .这显然也不是我们想要的结果

 

所以同时 设置max-age和 Expires 可以确保ie及 其他浏览器 都遵守以下原则

 

  1 在缓存文件过期之前的xhr请求 直接去 本地缓存读 而不发起http连接请求

  2 一旦缓存文件过期 才会发起请求 如果服务器响应头中 有Last Modified 或 Etag头 则 请求同时会带有 对应的 If-Modified-Since头或 If-None-Match 头  以便让服务器判断 是否需要返回新的 文件内容 或者 只返回 304 头 通知浏览器 本地缓存可以信任 它于服务器上的 文件相同.

   

 

 

 

 

二 对于不期待先后顺序的xhr请求 应放弃所谓xhr 资源管理.

 

即 通过一系列浏览器探测 以及http协议版本的 预期 以及当前 资源加载 所占用http连接数 等等状况 最终控制 实例化出的xhr对象个数 以及他们的用途…

 

这种行为看起来 可以避免 同时声明过多的xhr对象 而又不满足对应连接数 使可能过多的 xhr对象在浏览器队列中 空耗这 内存.

 

但恰恰相反 我们应在每次需要xhr时 立刻创建一个 并使其发送 需要的 请求 即可  我们要做的 只是在 success 回调函数处 即刻销毁xhr即可

 

这样做才可以 100% 有把握的 保证xhr的最大并发数而不需要我们自己去 分析 判断 猜测.

 

 

令一个需要注意的问题是 关于 主动给xhr 添加http请求头内容

 

 我的建议是 

   添加 Accept 头 比如 */*   因为一旦不设置此头  则个个浏览器的默认 Accept头 都不一样 比如firefox 就可能是一个很长的头 浪费带宽 . 所以同意使用 Accept 并制定为我们需要的类型 可以减少http请求中的数据量.

 

   一个有趣的问题 在于 如果 我们没有主动向xhr添加一个 If-Modified-Since 头的话则无论服务器返回码 是不是304   xhr.status 都将是200  除非 我们明确的添加了一个包含If-Modified-Since的请求头  这时xhr.status== 200 才是可信任的否则 . 一旦 是从缓存中读取的 内容  则状态总是200 而不是我们期望的 304 . 手动添加 If-Modified-Since 头 为一个 过早或过晚的日期(相对该文件在服务器上的 Last Modified 日期) 都将导致 服务器端校验缓存文件可靠性失效.从而服务器端 总是发送一个 200 状态码 并将最新文件数据异同 发送过来. 所以人为添加 If-Modified-Since头 需要谨慎 且保证其正确性. 如果我们并不需要确定 到底是从缓存读出数据还是 服务器端发送的数据 则 不建议人为添加 If-Modified-Since头.

 

  另外 xhr请求时 永远不要尝试 人工发送 一个 If-None-Match 头 给服务器 我们一般将会得到一个 400状态码即 bad Request 即使 我们的内容是一个看起来 合法的 有效的ETag值. 

posted @ 2010-06-04 09:50  Franky  阅读(1216)  评论(4编辑  收藏  举报