浏览器PATCH请求未自动携带If-Match头的责任与行为疑问
问题解答
是的,你需要手动在PATCH请求中添加If-Match请求头,浏览器不会自动为这类修改型请求注入该头信息。
为什么浏览器行为不一致?
- GET请求自动加
If-None-Match:这是浏览器缓存机制的标准行为,目的是验证本地缓存的资源是否仍与服务器端一致,从而避免重复下载未变更的资源,属于浏览器主动实现的性能优化,完全符合HTTP缓存规范。 - PATCH请求不自动加
If-Match:If-Match的作用是并发控制(乐观锁),确保你要修改的资源是你上次获取的版本,防止覆盖其他用户的修改。这属于业务逻辑层面的需求——并非所有PATCH请求都需要这类校验,浏览器无法判断你的业务场景是否需要,因此不会自动添加。
手动添加If-Match的实现示例
你可以先缓存GET请求返回的Etag值,再在PATCH请求中携带该值:
// 缓存获取到的Etag let cachedEtag = ''; document.getElementById('get-btn').addEventListener('click', async () => { const response = await fetch("http://test.local/api/v1/test", { method: 'GET', headers: { 'Accept': 'application/hal+json', 'Authorization': 'Bearer XXXXX', } }); // 保存Etag cachedEtag = response.headers.get('ETag'); }); document.getElementById('patch-btn').addEventListener('click', async () => { if (!cachedEtag) { // 处理未获取到Etag的情况,比如先发起GET请求 alert('请先获取资源信息'); return; } await fetch("http://test.local/api/v1/test", { method: 'PATCH', headers: { 'Accept': 'application/hal+json', 'Authorization': 'Bearer XXXXX', 'Content-Type': 'application/json', 'If-Match': cachedEtag // 手动添加If-Match头 }, body: JSON.stringify({}) }); });
补充说明
HTTP规范中仅要求浏览器对可缓存的GET/HEAD请求自动执行缓存验证逻辑(包括携带If-None-Match),但并未规定浏览器需要为PUT/PATCH等修改类请求自动添加If-Match或其他并发控制头。这类逻辑完全由开发者根据业务需求实现。
内容的提问来源于stack exchange,提问作者user19014551
相关产品推荐
相关产品推荐

