扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
来源:IT专家网 2011年3月5日
在使用基于PL/SQL的web应用程序时,mod_plsql的一个非常令人烦恼的方面是当你在数据库外使用图片时,你的浏览器似乎从不对它们进行缓存。使用过Cache-Control、Expires和Last-Modified头,但是似乎都不起作用。每一次重新加载页面时,浏览器就会重新加载所有从mod_plsql而来的图片,但是它会将从文件系统而来的图片从缓存中获得。这使得对于终端用户来说如果页面拥有大量图片的话页面会显得非常缓慢,而这些图片是可以被缓存的。
对于要使用大量存储在数据库中图片的项目来说,要解决这个缓存问题,可以使用Java将这些图片写到文件系统上,这样Apache就可以以被缓存的方式来使用它们了。在这么做之前,先使用Firebug和Wireshark来作些跟踪。关于这些工具有些事要注意。当使用Firebug>Net>Images来跟踪图片缓存时,一个浅灰色条显示一个缓存的图片而一个深灰色条显示非缓存图片。当使用wireshark时,右键单击相应的捕获包,例如一个图片的Get,然后选择“FollowT CP Stream”。这会按顺序显示给你这个包流。
我从跟踪Apache的一个静态页开始,它包含一些从文件系统而来的图片。我发现每一次重新加载页面的时候,浏览器都会重新提交相同的“Get”请求,当我按shift+refresh或是简单地刷新时,会相应地返回一个非缓存页面或缓存页面。一个问题是“If-Modified-Since”和“If-None-Match”头只在缓存页面上,不过我将采用缓存页面。所以,浏览器每次都请求图片(或文件),这意味着它不会缓存这些图片。所以,我是在服务器端丢了些东西。
下面的例子是Firefox和Apache之间的一个虚拟对话:
Firefox:获得logo.gif
Apache:HTTP200“OK”了, Etag:ABC123,Content-Length: 35, gif文件内容
Firefox:Get logo.gif,If-None-Match:ABC123
Apache:HTTP304“Not Modified”, Etag:ABC123,Content-Length:35, 头关闭了,没有文件返回
对于第一个对logo.gif的请求,Apache返回了一个Etag头和这个文件的内容。对于第二个请求,Firefox发送了Etag的值作为If-None-Match头。Apache比较了这些值并简单地返回了一个304状态,而不是图片,因为值是一样的。
什么是ETag?它是一个用于某个文件的唯一标识符,文件改变时它也要改变。它的相应请求头是“If-None-Match”。可以在“Last-Modified”响应头和“If-Modified-Since”请求头之间做相同的对比。HTTP规范认为Etag是一个“强”属性而“Last-Modified”是一个“弱”属性,所以我在这里将关注于Etag。
所以,以前我们一直希望Apache或mod_plsql能够缓存我们的图片,但实际上我们(PL/SQL程序员)是要做这个缓存的人。不过幸好它很简单,特别是现在你已了解了这个问题。
为了使其起作用,你需要做3件事:
使If-None-Match CGI环境变量可用于mod_plsq或内嵌网关。
将包含所有图片请求的Etag头发送回去。
当有一个图片请求时,比较Etag和If-None-Match头,返回一个304 Not Modified头或者返回这个图片。
如果你使用内嵌的PL/SQL网关,那么以SYS权限执行下面的代码添加2个CGI环境变量:
图1
如果你在使用Oracle HTTP服务器(Apache+mod_plsql),那么添加下面的代码到你的Database Access Descriptor(数据访问描述符,DAD)中,然后启动OHS来应用你的改变:
PlsqlCGIEnvironmentList HTTP_IF_NONE_MATCH
PlsqlCGIEnvironmentList IF_MODIFIED_SINCE
OK,现在看下代码:
图2
27-35行很重要,我们确定这个图片/文件是否改变了,并简单地返回一个304状态代码,而不是图片本身。注意我通过连接主键和最近更新/创建的日期(格式化为具有时间的Julian日期)来构建Etag头。这意味着如果这个图片或文件被更新了,那么日期就会改变,从而改变Etag。这反过来使你的浏览器可以下载更新的版本。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者