Fetch API 响应代码与网络选项卡响应代码不同

问题描述 投票:0回答:2

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

  1. 响应对象显示的响应代码与网络选项卡中显示的响应代码不同。
  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>
    );
}

控制台(注意右侧的响应代码)

javascript reactjs fetch-api
2个回答
0
投票

返回 304 - 200 作为获取结果

获取标准描述了这种行为这里

  1. 如果响应为空,则:

有关 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
钩子,可以确保此代码只会执行一次。


0
投票

我也遇到了这个问题,但事实证明我没有正确使用 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
}
© www.soinside.com 2019 - 2024. All rights reserved.