TypeError: Failed to fetch?

我在使用Fetch请求登录接口时报错TypeError: Failed to fetch

通过postman测试,接口返回值与预期一致。

但在浏览器内执行时就报错。

这是React的代码:

fetch(`${url}/admin/login`, {
            method: 'POST',
            headers: {'Content-Type':'application/json'},
            body: JSON.stringify({'name': n, 'password': p})
        })
            .then(r => r.json())
            .then(d => {
                if (d.hasOwnProperty('text'))
                    alert(d.hasOwnProperty('err') ? d.text + ':' + d.err : d.text)
                else if (d.hasOwnProperty('id') && d.hasOwnProperty('token'))
                    localStorage.setItem('token', d.token)
                else
                    alert('登录失败!请重试')
            })
            .catch(err => alert('Fetch Rejected:' + err))

同时,有一个百思不得其解的现象:

image.png

即十次请求里面,绝大部分都是已取消的状态(可以理解为这个fetch请求压根没有发出去?)
但是十次之中又偶尔一次可以请求成功,但紧接着的必然报错。

我以TypeError: Failed to fetch为关键字百度了相关帖子,似乎都在说应该在后端的代码逻辑内处理一下OPTIONS请求的预检,但从控制台的请求记录来看,压根连一个OPTIONS的请求都没发出过...(虽然我也按照建议的方案尝试过,但毫无例外地都没有凑效...)

跪求大佬指点ORZ..

阅读 17.4k
1 个回答

原因

导致fetch失败的原因是:未设置调用fetch的点击按钮的类型。

buttontype未设置时,其type默认取submit

buttontype=submit时,点击后默认的行为是提交数据并重新加载页面。

一旦页面重新加载,任何进行中的请求都不会再监听响应。

又因fetch为异步,所以控制台网络选项卡中显示状态为已取消。

  1. 已取消并非意味着请求未成功发出(更正一下上面问题中的描述);
  2. 为什么十次中有的成功有的不成功,大概率是因为,fetch的响应若快于页面的加载,则会成功,否则fetch失败。

解决

方案一

设置buttontypebutton,表示按钮无任何默认行为,所有行为由javascript自定义。

<button type='button' />

方案二

buttononclick回调函数中阻止默认的提交和刷新事件。

const f = e => {
    e.preventDefault()
    ...
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏