☰
HTTP条件请求怎样用ETag避免重复下载静态文件
2026/10/14 12:45:01 网站建设 项目流程

重复下载相同静态文件会浪费传输资源。本文用仅绑定本机的Python测试服务演示ETag和If-None-Match:正文未变化时返回304,变化后返回200,理解缓存验证与长期不发请求的区别。

环境与适用范围

需要Python 3标准库,本机端口18113空闲。只处理受控的GET请求,不提供TLS、登录和生产并发能力。以下是教学示例,未在真实服务器运行;代码只做本地语法及计算核查。

原理与取舍

ETag是表示资源版本的验证标识。客户端保存标识后用If-None-Match请求,服务器版本相同可返回304且不发送正文。它仍需要一次请求往返,不能把304等同于完全不访问服务器。

测试数据和响应边界

示例用SHA256为一段固定字节生成强验证标识,并发送Cache-Control: no-cache,允许缓存保存但要求复用前验证。这里只检查完全匹配的单个标识,没有实现通配符和多标识列表,不可直接作为完整HTTP协议实现。

可复现示例

# 保存为 etag_demo.py 并运行 python3 etag_demo.pyimporthashlibimportthreadingfromhttp.serverimportBaseHTTPRequestHandler,HTTPServerfromurllib.requestimportRequest,urlopenfromurllib.errorimportHTTPError payload=b"version-one\n"classHandler(BaseHTTPRequestHandler):defdo_GET(self):tag='"'+hashlib.sha256(payload).hexdigest()+'"'unchanged=self.headers.get("If-None-Match")==tag self.send_response(304ifunchangedelse200)self.send_header("ETag",tag)self.send_header("Cache-Control","no-cache")ifnotunchanged:self.send_header("Content-Length",str(len(payload)))self.end_headers()ifnotunchanged:self.wfile.write(payload)deflog_message(self,*_):passserver=HTTPServer(("127.0.0.1",18113),Handler)thread=threading.Thread(target=server.serve_forever,daemon=True)thread.start()url="http://127.0.0.1:18113/"try:withurlopen(url,timeout=3)asresponse:tag=response.headers["ETag"]print(response.status,response.read())request=Request(url,headers={"If-None-Match":tag})try:withurlopen(request,timeout=3)asresponse:print(response.status)exceptHTTPErrorasexc:try:assertexc.code==304print(exc.code,len(exc.read()))finally:exc.close()payload=b"version-two\n"withurlopen(request,timeout=3)asresponse:print(response.status,response.read())finally:server.shutdown()server.server_close()thread.join()

验证方法

执行后预期依次看到200和version-one、304与零正文、200和version-two。urllib把304按HTTPError交给调用方,示例单独核对状态而不是将其当网络失败重试。端口被占用时停止并选择另一空闲本机端口。上述为预期输出,不是已运行的服务器实测。

常见错误与局限

no-cache要求验证,no-store要求不保存,两者不能互换。压缩后的表示可能有不同ETag;通过代理、认证页面和多版本资源时要检查Vary与缓存权限。示例没有实现HEAD、弱验证标识比较和完整条件请求优先级;上线应使用成熟Web服务并核对真实响应头。

参考与创作关联

选题来自服务器配置资料整理。正文采用通用环境与受控样本,使用AI辅助撰写;未在对应服务器实际部署或压测。

RFC 9110 条件请求

Python HTTP服务文档

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询