1. 为什么在浏览器中访问是304,而通过linux下curl进行测试,却是200?
2. 304究竟是源站返回的?还是CDN节点返回的?
3. 如果源站返回304,那么客户端收到的会是304么?
4. ?????
状态码304百度百科结果:如果客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:客户端已经执行了GET,但文件未变化。
首先需要清楚304的请求原理:之所以会有304,是因为源站收到了来自客户端的对比需求(是否对比是客户端提的需求)。换句话说,只有当客户端在请求的时候提供了双方早已商榷好的对比参数,服务端才会进行参数对比,进而判断是否需要返回文件内容给客户端,若客户端未提供这些参数,那么服务端将直接返回200(文件内容)。而这些参数就是:
if-none-match:当服务端收到的request header中包含这个头部信息时,将获取其中的参数值(客户端缓存的文件的Etag值),与文件本身的Etag值进行对比,若一致,则返回304。
if-modified-since:当服务端收到的request header中包含这个头部信息时,将获取其中的参数值(客户端缓存的文件的Last-modified值),与文件本身的Last-modified时间进行对比,若一致,则返回304。
请仔细对比下方两个request header的区别,上为浏览器请求头(前提是浏览器已访问过该文件),下为linux请求头,你将发现浏览器的请求头中包含很多文件与CDN的信息,其中便包括下方红色方框的两个头部信息。
当服务端接收到这两个头部信息后,便会进行对比,发现文件未变化,则返回304。
如上例子,CDN节点若过期回源,源站返回304,那是否linux端也会接收到304呢?
不会。由于CDN的节点均为代理访问,因此CDN的中心节点接收到的304为源站返回,而边缘节点接收到的304为中心节点返回,客户端接收到的304为边缘节点返回。CDN节点过期回源时,将带着if-none-match if-modified-since两个头部进行验证,若文件未经修改,则返回304,但linux客户端在请求时并未带上if-none-match if-modified-since,因此CDN节点将直接返回200(并同时返回源文件数据包)。