首页 > 解决方案 > Fetch 触发了两次

问题描述

我有以下代码;

componentDidMount() {
    if (this.state.isLoggedIn) {
        return;
    }
    if (localStorage.getItem("token")) {
        fetch("https://localhost:8000/test", {
            method: "POST",
            headers: {
                "Authorization": `Bearer + ${localStorage.getItem("token")}`
            }
        })
    }
}

在安装时,我正在向我的服务器发送一个发布请求。服务器运行 express,中间件如下;

const authenticate = (req, res, next) => {
    console.log("auth triggered");
    res.set('Access-Control-Allow-Origin', '*')
    res.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
    console.log(`${req.headers.authorization}`)
    next()
}

我遇到的问题是每次调用 componentDidMount 时,服务器都会打印两个日志;

auth triggered
undefined
auth triggered
Bearer + testToken

是什么导致了这种行为?

标签: node.jsreactjs

解决方案


在您的authenticate()中间件中,添加以下内容:

console.log("auth", req.method, req.originalUrl); 

并查看哪些请求实际上是命中中间件。

一种可能性是跨域预飞行的 OPTIONS 请求,浏览器为某些类型的跨域请求发送该请求,以查看是否允许此特定的跨域调用(与它所做的其他检查分开)。这是完全正常和预期的,因为您的 POST 具有与之关联的自定义标头(请求中的某些内容会触发预飞行)。

如果您打开 Chrome 调试器并查看network选项卡,您还可以准确地看到浏览器发送到服务器的内容。在那里,您将看到浏览器在发送 POST 之前发送的 OPTIONS pre-flight(以及为什么您的中间件会被命中两次)。

关于 OPTIONS 飞行前的一些参考资料:

MDN:预检请求

MDN:CORS


推荐阅读