最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Error with axios: TypeError: Cannot read property 'status' of undefined - Stack Overflow

programmeradmin4浏览0评论

Ok, I have an interceptors in my index.js to refresh the token if the status code is 401, this works fine, but in login page if I return another status code from the server, the messages errors in the page not working, because the axios interceptors not receive a 401.

But if receive a 401, the interceptors work fine.

This is a screenshot about that. It returns a 404 from the server if not found the user.

The error is related with Login.vue, but if I delete the axios.interceptors in my index.js the "status" in Login.vue it works fine.

Interceptors

axios.interceptors.response.use(response => {
  return response;
}, error => {
  if (error.response.status === undefined) {
    return;
  } else {
    const code = error.response.status;
    if (code === 401) {
      localStorage.removeItem("token");
      axios.get("token/refresh", {
        params: {
          correo: window.localStorage.getItem("email")
        }
      }).then(response => {
        var refresh_token = response.data.token;
        localStorage.setItem("token", refresh_token);
      }).catch(error => {
        const response = error.response;
        console.log(response.data.errors);
      })
      return Promise.reject(error);
    }
  }
});

I tried in the interceptors, to use something like this:

if(error.response.status == undefined) return;

But it doesn't work.

Login Catch

          .catch(error => {
        this.loading = false;
        if (error.response.status != null) {
          switch (error.response.status) {
            case 400:
              this.alertError = true;
              this.errorMessage = "No estás autorizado para acceder.";
              this.loading = false;
              break;
            case 500:
              this.alertError = true;
              this.errorMessage =
                "Hay un problema con el servidor, disculpa las molestias.";
              this.loading = false;
              break;
            case 404:
              this.alertError = true;
              this.errorMessage = "Vuelve a ingresar tu contraseña";
              break;
            default:
              this.alertError = true;
              this.errorMessage =
                "Hay un error interno en el servidor, intenta de nuevo más tarde";
          }
        }
      })

How to handle this?

Ok, I have an interceptors in my index.js to refresh the token if the status code is 401, this works fine, but in login page if I return another status code from the server, the messages errors in the page not working, because the axios interceptors not receive a 401.

But if receive a 401, the interceptors work fine.

This is a screenshot about that. It returns a 404 from the server if not found the user.

The error is related with Login.vue, but if I delete the axios.interceptors in my index.js the "status" in Login.vue it works fine.

Interceptors

axios.interceptors.response.use(response => {
  return response;
}, error => {
  if (error.response.status === undefined) {
    return;
  } else {
    const code = error.response.status;
    if (code === 401) {
      localStorage.removeItem("token");
      axios.get("token/refresh", {
        params: {
          correo: window.localStorage.getItem("email")
        }
      }).then(response => {
        var refresh_token = response.data.token;
        localStorage.setItem("token", refresh_token);
      }).catch(error => {
        const response = error.response;
        console.log(response.data.errors);
      })
      return Promise.reject(error);
    }
  }
});

I tried in the interceptors, to use something like this:

if(error.response.status == undefined) return;

But it doesn't work.

Login Catch

          .catch(error => {
        this.loading = false;
        if (error.response.status != null) {
          switch (error.response.status) {
            case 400:
              this.alertError = true;
              this.errorMessage = "No estás autorizado para acceder.";
              this.loading = false;
              break;
            case 500:
              this.alertError = true;
              this.errorMessage =
                "Hay un problema con el servidor, disculpa las molestias.";
              this.loading = false;
              break;
            case 404:
              this.alertError = true;
              this.errorMessage = "Vuelve a ingresar tu contraseña";
              break;
            default:
              this.alertError = true;
              this.errorMessage =
                "Hay un error interno en el servidor, intenta de nuevo más tarde";
          }
        }
      })

How to handle this?

Share Improve this question edited Jul 21, 2021 at 4:15 Vidarshan Rathnayake 4841 gold badge10 silver badges22 bronze badges asked Sep 3, 2018 at 19:08 Isaías Orozco ToledoIsaías Orozco Toledo 2,1195 gold badges23 silver badges36 bronze badges 4
  • 3 Have you tried logging the error variable to find out what properties it contains? (Off the top of my head I think you probably want error.status not error.response.status, but it'd be easier to check than to guess.) – Daniel Beck Commented Sep 3, 2018 at 19:15
  • @DanielBeck error.status not works, error.response contains all: data, status, headers, reques, config... – Isaías Orozco Toledo Commented Sep 3, 2018 at 19:20
  • 1 @IsaíasOrozcoToledo is the problem solved? – Bharathvaj Ganesan Commented Sep 8, 2018 at 3:15
  • @BharathvajGanesan yes – Isaías Orozco Toledo Commented Sep 12, 2018 at 15:18
Add a ment  | 

2 Answers 2

Reset to default 4

A response interceptor must return a response, a resolved promise or a rejected promise.

Your interceptor has logic paths that don't return anything, hence your problem.

You want something like this...

axios.interceptors.response.use(
  (r) => r,
  (error) => {
    if (error.response.status === 401) {
      localStorage.removeItem("token");
      // make sure to return the new promise
      return axios
        .get("token/refresh", {
          params: {
            correo: window.localStorage.getItem("email"),
          },
        })
        .then((response) => {
          localStorage.setItem("token", response.data.token);
          // now replay the original request
          return axios.request(error.config);
        });
    }
    // not a 401, simply fail the response
    return Promise.reject(error);
  }
);

From your implementation, you are trying to refresh the token. What you can do is to shift the refresh token handling to the server side. So If the token expires the server will send the token in the header and inside the axios interceptors write a code as follows to update the local storage when the header contains auth token. Below a sample implementation from my side project

export default () => {
const authTokenJson = localStorage.getItem('auth');

let axiosInstance = null;

if (authTokenJson) {
    const tokens = JSON.parse(authTokenJson);
    axiosInstance = axios.create({
        headers: {
            'authorization': `Bearer ${tokens.token}`,
            'refresh-token': `${tokens.refreshToken}`
        }
    });
} else {
    axiosInstance = axios.create();
}

axiosInstance.interceptors.response.use(
    response => {
        console.log(response);
        const tokens = {
            token: response.headers['authorization'],
            refreshToken: response.headers['refresh-token']
        };
        if (tokens.token && tokens.refreshToken) {
            setTokens(JSON.stringify(tokens));
        }
        return response;
    },
    err => {
        if (err.response.status === 401) {
            EventBus.$emit('errors:401');
        }
        return Promise.reject(err);
    }
);
return axiosInstance;
};
发布评论

评论列表(0)

  1. 暂无评论