【问题标题】:How can I get the status code from an HTTP error in Axios?如何从 Axios 中的 HTTP 错误中获取状态码?
【发布时间】:2022-01-16 01:32:19
【问题描述】:

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

axios
  .get('foo.com')
  .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'}

【问题讨论】:

    标签: javascript axios


    【解决方案1】:

    你看到的是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);
        }
      });
    

    【讨论】:

    • 如果我不引用 response 属性,你能解释一下它自动变成字符串背后的魔力吗?
    • console.log 使用toString 方法格式化Error 对象。它与引用response 属性无关。
    • 我仍然很困惑,这是对错误对象的特殊性还是?如果我 console.log 一个对象,我得到的是对象,而不是字符串。
    • 这取决于实现。例如,console.loghandlesError 对象作为特例的 node.js 实现。我不能说它在浏览器中是如何实现的,但是如果你在 Chrome DevTools 控制台中调用 console.log({ foo: 'bar' });console.log(new Error('foo'));,你会看到结果看起来不同。
    • 那么一定是原生的东西。不过还是很奇怪。
    【解决方案2】:

    使用 TypeScript,使用正确的类型很容易找到您想要的内容。

    这使一切变得更容易,因为您可以通过自动完成获得该类型的所有属性,因此您可以了解响应和错误的正确结构。

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

    此外,您可以将参数传递给这两种类型,以告知您在 response.data 中的期望,如下所示:

    import { AxiosResponse, AxiosError } from 'axios'
    axios.get('foo.com')
      .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)
      })
    

    【讨论】:

    • 我正试图让我的团队切换到 Typescript 以获得这种清晰度。
    • 这让一切变得更容易,因为您可以通过智能感知获取该类型的所有属性,因此您可以了解响应和错误的正确结构
    【解决方案3】:

    正如@Nick 所说,当您 console.log 一个 JavaScript Error 对象时看到的结果取决于 console.log 的确切实现,这会有所不同并且 (imo) 使检查错误非常烦人。

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

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

    【讨论】:

    • 目前,这不起作用。它不显示 error.response 中的内容。
    • JSON.stringify(error) 在这种情况下可能会引发 Circular dependency 错误。
    【解决方案4】:

    请求配置中有一个名为validateStatus 的新选项。您可以使用它来指定当状态 300(默认行为)时不抛出异常。示例:

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

    【讨论】:

      【解决方案5】:

      您可以使用扩展运算符 (...) 将其强制转换为这样的新对象:

      axios.get('foo.com')
          .then((response) => {})
          .catch((error) => {
              console.log({...error}) 
      })
      

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

      【讨论】:

        【解决方案6】:

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

        const HttpClient = axios.create({
          baseURL: env.baseUrl,
        });
        
        HttpClient.interceptors.response.use((response) => {
          return response;
        }, (error) => {
          return Promise.resolve({ error });
        });
        

        【讨论】:

        • 使用拦截器的具体优势是什么?
        • 您可以在请求或响应被 then 或 catch 处理之前拦截它们。
        【解决方案7】:

        为了获取服务器返回的http状态码,可以在axios选项中添加validateStatus: status =&gt; true

        axios({
            method: 'POST',
            url: 'http://localhost:3001/users/login',
            data: { username, password },
            validateStatus: () => true
        }).then(res => {
            console.log(res.status);
        });
        

        这样,每个 http 响应都会解析从 axios 返回的承诺。

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

        【讨论】:

          【解决方案8】:

          整个错误只能使用 error.response 来显示:

          axios.get('url').catch((error) => {
                if (error.response) {
                  console.log(error.response);
                }
              });
          

          【讨论】:

            【解决方案9】:

            您可以将错误放入一个对象并记录该对象,如下所示:

            axios.get('foo.com')
                .then((response) => {})
                .catch((error) => {
                    console.log({error}) // this will log an empty object with an error property
                });
            

            希望这对那里的人有所帮助。

            【讨论】:

              【解决方案10】:

              仅获取 error 不会返回对象,这确实很奇怪。在返回 error.response 时,您可以访问所需的大部分反馈信息。

              我最终使用了这个:

              axios.get(...).catch( error => { return Promise.reject(error.response.data.error); });
              

              它提供了我需要的东西:状态码 (404) 和错误的文本消息。

              【讨论】:

                【解决方案11】:

                使用 Axios

                    post('/stores', body).then((res) => {
                
                        notifyInfo("Store Created Successfully")
                        GetStore()
                    }).catch(function (error) {
                
                        if (error.status === 409) {
                            notifyError("Duplicate Location ID, Please Add another one")
                        } else {
                            notifyError(error.data.detail)
                        }
                
                    })
                

                【讨论】:

                  【解决方案12】:

                  这是一个已知的bug,尝试使用"axios": "0.13.1"

                  https://github.com/mzabriskie/axios/issues/378

                  我遇到了同样的问题,所以我最终使用了"axios": "0.12.0"。对我来说效果很好。

                  【讨论】:

                  • 这不是我遇到的同一个问题,当我登录error时甚至没有涉及到对象
                  【解决方案13】:

                  这是我的代码:为我工作

                   var jsonData = request.body;
                      var jsonParsed = JSON.parse(JSON.stringify(jsonData));
                  
                      // message_body = {
                      //   "phone": "5511995001920",
                      //   "body": "WhatsApp API on chat-api.com works good"
                      // }
                  
                      axios.post(whatsapp_url, jsonParsed,validateStatus = true)
                      .then((res) => {
                        // console.log(`statusCode: ${res.statusCode}`)
                  
                              console.log(res.data)
                          console.log(res.status);
                  
                          // var jsonData = res.body;
                          // var jsonParsed = JSON.parse(JSON.stringify(jsonData));
                  
                          response.json("ok")
                      })
                      .catch((error) => {
                        console.error(error)
                          response.json("error")
                      })
                  

                  【讨论】:

                    【解决方案14】:
                    Axios. get('foo.com')
                    .then((response) => {})
                    .catch((error) => {
                        if(error. response){
                           console.log(error. response. data)
                           console.log(error. response. status);
                    
                          }
                    })
                    

                    【讨论】:

                    • 虽然此代码可能会为问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并将这些知识应用到他们自己的代码中。在解释代码时,您也可能会以赞成票的形式从用户那里获得积极的反馈。
                    猜你喜欢
                    • 2022-12-15
                    • 2018-08-22
                    • 2014-07-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-08-22
                    • 2012-05-14
                    • 1970-01-01
                    相关资源
                    最近更新 更多