【问题标题】:Authentication Vuex+Axios wrong url request status 404认证 Vuex+Axios 错误 url 请求状态 404
【发布时间】:2019-06-17 13:02:39
【问题描述】:

我正在尝试使用我正在使用的 API 进行身份验证,但是当我尝试登录时收到以下响应: “加载资源失败:服务器响应状态为 404(未找到)[http://localhost:8080/localhost:5000/api/login]

我认为问题出在 axios 上,因为它是使用我本地的 Vue 应用地址+apiAdress 来做请求的。

main.js:

import axios from 'axios'
Vue.use(axios)
axios.defaults.baseURL = process.env.VUE_APP_API; //(http://localhost:5000/api

模块/auth.js:

import { AUTH_REQUEST, AUTH_ERROR, AUTH_SUCCESS, AUTH_LOGOUT } from '../actions/auth'
import { USER_REQUEST } from '../actions/user'
import axios from 'axios'

const state = { token: localStorage.getItem('user-token') || '', status: '', hasLoadedOnce: false }

const getters = {
  isAuthenticated: state => !!state.token,
  authStatus: state => state.status,
}

const actions = {
  [AUTH_REQUEST]: ({commit, dispatch}, user) => {
    return new Promise((resolve, reject) => {
     commit(AUTH_REQUEST)
  axios({url: '/login', data: user, method: 'POST'})
  .then(resp => {
    localStorage.setItem('user-token', resp.token)
    // Here set the header of your ajax library to the token value.
    axios.defaults.headers.common['Authorization'] = resp.token
    commit(AUTH_SUCCESS, resp)
    dispatch(USER_REQUEST)
    resolve(resp)
  })
  .catch(err => {
    commit(AUTH_ERROR, err)
    localStorage.removeItem('user-token')
    reject(err)
  })
})
},
}

const mutations = {
  [AUTH_REQUEST]: (state) => {
  state.status = 'loading'
  },
  [AUTH_SUCCESS]: (state, resp) => {
    state.status = 'success'
    state.token = resp.token
    state.hasLoadedOnce = true
  },
  [AUTH_ERROR]: (state) => {
  state.status = 'error'
  state.hasLoadedOnce = true
  },
  [AUTH_LOGOUT]: (state) => {
    state.token = ''
  }
}

export default {
 state,
 getters,
 actions,
 mutations,
}

登录.vue:

  methods: {
    login() {
      const { username, password } = this
      this.$store.dispatch(AUTH_REQUEST, { username, password }).then(() => {
      this.$router.push('/')
   })
    },

【问题讨论】:

  • 为什么不使用完整的api路径?试试这个:axios({url: 'localhost:5000/api', data: user, method: 'POST'})
  • 如果你有一个不同的 api 端点用于开发、测试和生产

标签: javascript authentication vue.js axios vuex


【解决方案1】:

你根本不需要在 main 中定义 axios。

另外,axios 不是 vue 插件,所以Vue.use(axios) 什么都不做。

在你的 auth.js 中你可以创建一个实例

const axios = require('axios');

const axiosInstance = axios.create({
  baseURL: process.env.VUE_APP_API
});

在您的操作中,使用 axios 实例而不是 axios

const actions = {
  [AUTH_REQUEST]: ({commit, dispatch}, user) => {
    return new Promise((resolve, reject) => {
     commit(AUTH_REQUEST)
  axiosInstance({url: '/login', data: user, method: 'POST'})
  .then(resp => {
    localStorage.setItem('user-token', resp.token)
    // Here set the header of your ajax library to the token value.
    axios.defaults.headers.common['Authorization'] = resp.token
    commit(AUTH_SUCCESS, resp)
    dispatch(USER_REQUEST)
    resolve(resp)
  })
  .catch(err => {
    commit(AUTH_ERROR, err)
    localStorage.removeItem('user-token')
    reject(err)
  })
})

但是,这可能会导致在创建实例后更新标头出现问题,因此您可能需要使用一些巧妙的方法来解决这个问题。

一种方法是使用函数而不是值,这样每当您进行调用时,它就会使用本地存储中的数据

const axiosInstance = axios.create({
  baseURL: process.env.VUE_APP_API,
  headers: {
    Authorization: {
      toString () {
        return `Bearer ${localStorage.getItem('user-token')}`
      }
    }
  }
})

另一种方法是每次拨打电话时都创建一个新请求

const actions = {
  [AUTH_REQUEST]: ({ commit, dispatch }, user) => {
    return new Promise((resolve, reject) => {
      const axiosInstance = axios.create({
        baseURL: process.env.VUE_APP_API
      });
      commit(AUTH_REQUEST)
      axiosInstance({
          url: '/login',
          data: user,
          method: 'POST'
        })
        .then(resp => {
          localStorage.setItem('user-token', resp.token)
          // Here set the header of your ajax library to the token value.
          axios.defaults.headers.common['Authorization'] = resp.token
          commit(AUTH_SUCCESS, resp)
          dispatch(USER_REQUEST)
          resolve(resp)
        })
        .catch(err => {
          commit(AUTH_ERROR, err)
          localStorage.removeItem('user-token')
          reject(err)
        })
    })
  },
  [SECURE_REQUEST]: ({ commit, dispatch }, user) => {
    return new Promise((resolve, reject) => {
      const axiosInstance = axios.create({
        baseURL: process.env.VUE_APP_API,
        headers: {
          'Authorization': 'Bearer ' + localStorage.getItem('user-token')
        }
      });
      commit(SECURE_REQUEST)
      axiosInstance({
          url: '/getData',
          data: user,
          method: 'POST'
        })
        // ...
    })
  },
}

另一个选项(这是我这些天使用的)是使用devServer.proxy 配置。这需要您使用 Vue-Cli-3。它还假设最终的静态包将与您的 API 在同一台服务器上运行,这可能不适合您。

另外,请查看此解决方案:https://github.com/axios/axios/issues/1383#issuecomment-405900504

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-15
    • 2022-11-13
    • 2021-04-10
    • 2021-10-13
    • 2021-06-25
    • 2020-09-18
    • 2019-10-12
    • 2019-09-12
    相关资源
    最近更新 更多