如何在Axios中获取HTTP错误的状态码?

559

这可能看起来很蠢,但我正在尝试在Axios请求失败时获取错误数据。

axios
  .get('foo.example')
  .then((response) => {})
  .catch((error) => {
    console.log(error); //Logs a string: Error: Request failed with status code 404
  });

是否可以返回一个对象,而不是字符串,包括状态码和内容?例如:

而不是字符串,是否可能获取带有状态码和内容的对象?例如:

Object = {status: 404, reason: 'Not found', body: '404 Not found'}
16个回答

1055

你看到的是error对象的toString方法返回的字符串。(error不是一个字符串。)

如果已从服务器接收到响应,则error对象将包含response属性:

axios.get('/foo')
  .catch(function (error) {
    if (error.response) {
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    }
  });

29
你能否解释一下,如果我不引用 response 属性,它是如何自动转换为字符串的魔法? - Sebastian Olsen
27
console.log 使用 toString 方法来格式化 Error 对象,与引用 response 属性无关。 - Nick Uraltsev
9
我还是感到困惑,这与错误对象有关吗?如果我console.log一个对象,我得到的是对象而不是字符串。 - Sebastian Olsen
9
这取决于实现方式。例如,console.log 在 node.js 的实现中将 Error 对象作为一种特殊情况来处理。我无法确定它在浏览器中的具体实现方式,但是如果你在 Chrome DevTools 控制台中调用 console.log({ foo: 'bar' });console.log(new Error('foo'));,你会发现结果看起来不同。 - Nick Uraltsev
11
那肯定是本地的事情了。不过还是有点奇怪。 - Sebastian Olsen
显示剩余12条评论

72

使用TypeScript,只需要正确的类型就可以轻松找到所需内容。

这样做使一切都变得更加容易,因为你可以通过自动完成获取类型的所有属性,从而了解响应和错误的正确结构。

import { AxiosResponse, AxiosError } from 'axios'

axios.get('foo.example')
  .then((response: AxiosResponse) => {
    // Handle response
  })
  .catch((reason: AxiosError) => {
    if (reason.response!.status === 400) {
      // Handle 400
    } else {
      // Handle else
    }
    console.log(reason.message)
  })

此外,您可以向这两种类型传递参数,以告诉它们您期望在response.data中看到什么,例如:response.data
import { AxiosResponse, AxiosError } from 'axios'
axios.get('foo.example')
  .then((response: AxiosResponse<{user:{name:string}}>) => {
    // Handle response
  })
  .catch((reason: AxiosError<{additionalInfo:string}>) => {
    if (reason.response!.status === 400) {
      // Handle 400
    } else {
      // Handle else
    }
    console.log(reason.message)
  })

4
我正在努力让我的团队转换到 TypeScript,以获得这种清晰度。 - GHOST-34
这样做可以更方便,因为您可以通过智能感知获取类型的所有属性,从而了解响应和错误的正确结构。 - Ger
我不认为这里的非空断言(在代码行 if (reason.response!.status ...) 上)是安全的 - 如果您收到零状态码(例如,在返回响应之前网络中断),reason.response将变为undefined,并且您会在那里遇到TypeError错误。 - Ian Kim

27

正如@Nick所说,当您在JavaScript中console.log一个Error对象时看到的结果取决于console.log的具体实现,这种实现因人而异,(依我之见)使检查错误变得非常烦人。

如果您想查看完整的Error对象及其携带的所有信息,可以绕过toString()方法,只需使用JSON.stringify

axios.get('/foo')
  .catch(function (error) {
    console.log(JSON.stringify(error))
  });

1
目前,这个功能不起作用。它没有显示错误响应中的内容。 - Andresa Martins
2
在这种情况下,JSON.stringify(error) 是抛出 循环依赖 错误的潜在候选。 - Coke

22

请求配置中有一个名为validateStatus的新选项。您可以使用它来指定如果状态码在100以下或300以上,则不抛出异常(默认行为是抛出异常)。例如:

const {status} = axios.get('foo.example', {validateStatus: () => true})

14
你可以使用展开运算符 (...) 将它强制转换成一个新对象,像这样:
axios.get('foo.example')
    .then((response) => {})
    .catch((error) => {
        console.log({...error})
})

注意:这将不会是 Error 的一个实例。


12

我正在使用这些拦截器来获取错误响应。

const HttpClient = axios.create({
  baseURL: env.baseUrl,
});

HttpClient.interceptors.response.use((response) => {
  return response;
}, (error) => {
  return Promise.resolve({ error });
});

1
使用拦截器的具体优势是什么? - spencer741
1
您可以在请求或响应被处理之前拦截它们,以便进行处理或捕获。 - Tan

10
为了获取服务器返回的HTTP状态码,您可以将validateStatus: status => true添加到axios选项中:
axios({
    method: 'POST',
    url: 'http://localhost:3001/users/login',
    data: { username, password },
    validateStatus: () => true
}).then(res => {
    console.log(res.status);
});

这样一来,每次http响应都会解决由axios返回的promise。

https://github.com/axios/axios#handling-errors


9
只有使用"error.response"才能显示完整错误,例如:
axios.get('url').catch((error) => {
      if (error.response) {
        console.log(error.response);
      }
    });

7
const handleSubmit = (e) => {
e.preventDefault();
// console.log(name);
setLoading(true);
createCategory({ name }, user.token)
  .then((res) => {
   // console.log("res",res);
    setLoading(false);
    setName("");
    toast.success(`"${res.data.name}" is created`);
    loadCategories();
  })
  .catch((err) => {
    console.log(err);
    setLoading(false);
    if (err.response.status === 400) toast.error(err.response.data);//explained in GD
  });

};

查看控制台日志,您就会清楚地了解。

在这里输入图片描述


3
Axios. get('foo.example')
.then((response) => {})
.catch((error) => {
    if(error. response){
       console.log(error. response. data)
       console.log(error. response. status);

      }
})

虽然这段代码可能提供了问题的解决方案,但最好添加上为什么/如何运作的上下文。这可以帮助未来的用户学习,并将这些知识应用到他们自己的代码中。当代码被解释时,您还可能会得到用户的积极反馈,例如点赞。 - borchvm
我认为我理解了这段代码的工作原理...它正在检查响应是否存在,然后console.log...我认为这是一个好的解决方案。 - Jenuel Ganawed
请不要发布仅包含代码的答案。未来的读者会感激您解释为什么这个答案回答了问题,而不是从代码中推断出来。此外,由于这是一个旧问题,请解释它如何补充其他答案。实际上,它与被接受的答案基本相同。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接