我正在创建一个 React 组件,旨在根据页面是否被缓存来检查隐私策略页面的更新。我有两个问题 -
代码
//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>
);
}
获取标准描述了这种行为这里。
- 如果响应为空,则:
有关 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)
块将被执行多次,从而触发多个API调用。
通过使用带有空依赖项数组的
useEffect
钩子,可以确保此代码只会执行一次。
我也遇到了这个问题,但事实证明我没有正确使用 Fetch API。
我假设当我等待 fetch 的响应时,它实际上给了我来自服务器的响应,但它是响应对象的承诺。我的期望来自于我对 Axios HTTP 的使用。他们的运作方式不同。
这就是我拥有的
async function someRequest(){
const response = await fetch("doSomeRequest", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: '[email protected]'
})
});
//This showed the same type of response as OP question.
console.log(response);
...Do Somethings with response
}
我缺少的部分是
response.json()
。这确实是 MDN Fetch API 上的第一个示例
这是完整的更正代码。
async function someRequest(){
const response = await fetch("doSomeRequest", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: '[email protected]'
})
});
const data = response.json();
//It now shows the same info as the network tab.
console.log(response);
...Do Somethings with response
}