javascript - 获取 API 响应代码与网络选项卡响应代码不同
问题描述
我正在创建一个 React 组件,该组件旨在根据页面是否被缓存来检查隐私策略页面的更新。我有两个问题-
- Response 对象显示的响应代码与网络选项卡中显示的响应代码不同。
- 不太重要的是,请求被发送了两次,我不确定为什么。这可能是我的逻辑问题或由应用程序中的其他内容引起的。
编码
//Set the state to undefined initial, it'll
const [ppChanged, setPPStatus] = useState(undefined);
function checkPrivacyPolicyChanged(url) {
try {
fetch(url)
.then(
response => {
console.log("Response: ", response)
if (response.ok && response.status !== 304) {
//If the response code is 200-299 (ok status), and isn't cached (as indicated by status 304)
//Tell the component that the privacy policy has had changes since the user last saw it
setPPStatus(true);
} else if (response.status == 304) {
setPPStatus(false);
} else {
console.log(response);
}
},
//Error handling
error => {throw Error(error)}
)
}
catch(err) {
console.log(err)
}
}
//If we haven't determined the privacy policy state yet, check for it. (Using manifest.json for testing purposes)
if (ppChanged == undefined) {
checkPrivacyPolicyChanged("/manifest.json");
}
let color = "green";
//If a change to the privacy policy is detected, give a visual cue
if (ppChanged) {color = "purple"};
return(
<div style={{color}}>
{props.children}
</div>
);
}
解决方案
返回 304 - 200 作为获取结果
fetch 标准在这里描述了这种行为。
- 如果响应为空,则:
有关哪些null body status
是101
、204
、205
或的状态的描述,请参阅状态304
。
10.4 如果设置了 revalidatingFlag 并且 forwardResponse 的状态是 304,那么:
10.4.1 使用 forwardResponse 的头列表更新 storedResponse 的头列表,根据 HTTP 缓存的“验证时刷新存储的响应”一章。[HTTP缓存]
这也会更新缓存中存储的响应。
10.4.2 将响应设置为storedResponse。
这意味着200
状态代码来自您的浏览器之前存储的响应,并且正在提供服务,因为它收到了一个304
. 这是有道理的,因为浏览器将无法给您响应,除非它再次查询资源(这是在此304 - Not modified
状态下试图避免的)。
备择方案
您可以改为跟踪请求的以下标头之一,并将这些标头与先前存储的值进行比较:
请求被发送两次
正如评论中提到的,解决方案是使用useEffect-hook。
useEffect(() => {
...
}, []); // Note the empty dependency array ensures that this code will only be executed once during the lifetime of this component.
之所以需要这个,是因为在渲染过程中,这个函数会被多次执行(例如,在调用 后更新状态setPPStatus
)。
重新执行该函数时,如果更新还没有发生,if (ppChanged == undefined)
-block会被执行多次,从而触发多次API调用。
通过将useEffect
-hook 与空的依赖数组一起使用,您可以确保此代码只会执行一次。
推荐阅读
- ruby-on-rails - 如何忽略 rspec VCR 中特定主机的请求正文匹配?
- python - 如何在没有任何库的情况下计算特征值和特征向量
- angular - 无法读取未定义角度 6 的属性
- http - 逗号分隔的列表在 Content-Type 标头中有效吗?
- python - 是否可以控制控制台输出的“光标”/向标准输出添加偏移量而不覆盖占据偏移量的字符?
- javascript - d3.js 气泡分布以匹配容器尺寸
- java - 如何使用Java获取目录中最旧的文件
- url - 赛普拉斯:如何检查按钮网址?
- java - 是否可以使用相同的 FileWriter 文件并从多种方法写入它?
- regex - 我需要解析文本以找到短语的开头、中间和结尾,完全替换开头,保留中间,并修改结尾