“304 Not Modified”是如何工作的?

194
  • "304 Not Modified"响应是如何生成的?

  • 浏览器如何确定HTTP请求的响应是否为304?

  • 它是由浏览器设置还是从服务器发送?

  • 如果是由服务器发送,服务器如何知道缓存中可用的数据,也如何将304设置为图像?

我的猜测,如果它是由浏览器生成的:

function is_modified()
{
    return get_data_from_cache() === get_data_from_url();
}

function get_data_from_cache()
{
    return some_hash_or_xxx_function(cache_data);
}

function get_data_from_url()
{
     return some_hash_or_xxx_function(new_data);
}

function some_hash_or_xxx_function(data)
{
     // Do something with the data.
     // What is that algorithm?
     return result;
}

console.log(is_modified());

我依赖于第三方API提供程序来获取数据、解析并将其推送到我的数据库。每次请求时,数据可能会更改,也可能不会更改,但标头始终发送200。我不想解析、检查数据库中的最后一个唯一ID等等…来确定数据的更改,也不想直接比较结果,而是使用md5()sha1()crc32()散列化结果,这很有效,但我想知道确定304的算法。

我想使用同样的算法来确定我的数据是否有变化。


2
是的,我在谷歌上搜索了“304未修改如何工作”,但没有得到任何答案。 - VenomVendor
1
你需要更加通用一些。https://www.google.com/search?q=http%20caching - SLaks
2个回答

220

当浏览器将内容放入缓存时,它也会存储服务器返回的Last-ModifiedETag标头信息。

浏览器随后发送一个请求,带有If-Modified-SinceIf-None-Match标头,告诉服务器如果内容仍具有该日期或ETag,则发送304。

服务器需要计算每个资源版本的修改日期或ETag的方法; 通常来自文件系统或单独的数据库列。


1
"ETag"是一个关键词,通过头部检查"ETag"在"响应头"和"缓存响应头"中保持不变,你能告诉我背后的算法吗?我已经更新了我的问题,说明了我的要求。 - VenomVendor
4
ETag 只是一个字段,服务器可以在其中存储唯一标识符(通常为哈希值、版本号或向量时钟)。它并不会帮助你计算出该标识符;这取决于你的服务器端代码。 - SLaks
1
@SLaks:如果页面有一个数据库调用会发生什么......数据库中的数据有可能已经更改......在这种情况下,检查最后修改的调用是没有意义的,对吗?......如何处理这种情况? - user1050619
3
服务器需要确保ETag准确无误。如果您显示来自数据库的数据,则需要包含该标记。 - SLaks
还有一个未明确的问题,如果你设定了很大的 max-age,那么浏览器是否需要发出请求呢?(因为它可以使用 304 来进行存根,并且根本不需要发出请求)……例如针对“指纹识别”的资源(它们永久有效)。否则,max-age 的意义何在呢? - Andy Hayden
显示剩余2条评论

24

Last-Modified:请求对象的最后修改日期

If-Modified-Since:如果最后修改日期未更改,则允许返回304 Not Modified。

ETag:ETag是Web服务器为URL上找到的资源的特定版本分配的不透明标识符。如果该URL上的资源表示发生更改,则分配一个新的和不同的ETag。

If-None-Match:如果ETag未更改,则允许返回304 Not Modified。

浏览器使用日期(Last-Modified)或ID(ETag)存储缓存,当您需要再次请求URL时,浏览器将带有以下标头的请求消息发送:

输入图像说明

当if语句为False时,服务器将返回304,并且浏览器将使用缓存。


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