谷歌浏览器如何缓存PDF文件

12

我已经构建了一个小型的PHP/MySQL内部应用程序来托管和排序文档。所有工作都很完美,直到涉及更新文件时出现问题,特别是.PDF文件。当用户更新.PDF文件时,新文件会按预期存储在服务器上,并删除旧版本。只要用户从未打开过旧版本,就可以获取新版本。

现在的问题是....如果用户曾经打开过旧版本的.PDF文件,即使实际上只有新版本在服务器上,当用户单击链接查看文档时,他们也不会获得更新后的版本。

我猜测Google Chrome浏览器在某个地方缓存了旧版本的PDF文件。如何解决这个问题?由于用户数量众多,一些文档每天更新的次数也很多,要求用户手动清除任何缓存不切实际。

3个回答

24
你在这里真的有四个选择:
1. 每次更新时更改文件名 2. 通过添加动态GET参数生成唯一的HREF 3. 使用文件的时间戳来生成新的动态GET参数 - 这样可以同时享受缓存的好处,并在文件可用时提供新的文件 4. 发送头信息告诉浏览器始终从服务器下载最新版本 选项1 - 在所有情况下都有效。可能难以维护
echo '<a href="/path/to/'.$row['FILENAME_FROM_DATABASE'].'">PDF</a>';

// Could produce something like:
// <a href="/path/to/file_v5.pdf">PDF</a>

选项2 - 在99%的情况下有效。
echo '<a href="/path/to/file.pdf?q='.htmlentities(microtime(true)).'">PDF</a>';

选项3 - 在99%的情况下有效
echo '<a href="/path/to/file.pdf?q='.htmlentities(filemtime('/path/to/file.pdf')).'">PDF</a>';

选项4 - 在99%的情况下有效。
header("Pragma: public");
header("Cache-Control: maxage=1"); // <-- important
header('Expires: '.gmdate('D, d M Y H:i:s', time()+1).' GMT');
header('Content-type: application/pdf');
exit(file_get_contents('/path/to/file.pdf'));

我使用选项2,但使用返回秒级Unix时间戳的time()函数。microtime()函数返回一个浮点数/字符串。将其附加到URL中可能不太安全。 - Antonio Garcia Marin

2
在HTML5中,您可以强制浏览器不要缓存某些域(或根本不缓存,或者如果可用则使用缓存等)-请参见https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache 将此添加到您的<!doctype html><head>部分:
<html manifest="my.cache">

在您的文档根目录上创建一个名为my.cache的文件,其中包含以下内容:
CACHE MANIFEST  
CACHE  
# dont force any caching 
NETWORK:
#force downloads form your site not to use cache
your-site.com

这强制确保没有任何内容被缓存。
如果您有pdf下载的路径,请使用它(这样除了PDF之外,您网站上的其他文件将被缓存)
在浏览器中尝试此操作。记得先清除缓存! :) 当您发现每个PDF都被下载时,无论文件名或标头如何。

-2
我会提供第三个选项,通过在链接后附加一个动态参数来下载文件,例如:
    <a href="http://host.com/my_file.pdf?t=<?php time(); ?>">My File</a>

那应该可以绕过缓存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接