首页 > 解决方案 > 获取 API 响应代码与网络选项卡响应代码不同

问题描述

我正在创建一个 React 组件,该组件旨在根据页面是否被缓存来检查隐私策略页面的更新。我有两个问题-

  1. Response 对象显示的响应代码与网络选项卡中显示的响应代码不同。
  2. 不太重要的是,请求被发送了两次,我不确定为什么。这可能是我的逻辑问题或由应用程序中的其他内容引起的。

编码

    //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>
    );
}

控制台(注意右侧的响应代码) 控制台和网络选项卡输出

标签: javascriptreactjsfetch-api

解决方案


返回 304 - 200 作为获取结果

fetch 标准在这里描述了这种行为。

  1. 如果响应为空,则:

有关哪些null body status101204205或的状态的描述,请参阅状态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 与空的依赖数组一起使用,您可以确保此代码只会执行一次。


推荐阅读