javascript - Att göra axios global i Vue-projektet fungerar inte


Hittills hade jag importerat axios i varje Vue-komponent där jag ville göra HTTP-förfrågningar, på det här sättet.

<script lang="ts">
import axios from 'axios';

@Component
export default class ExamplePage extends Vue {
  created(): void {
    axios.post(some_path);
  }
}

Men nu vill jag definiera en global interceptor för alla axios-förfrågningar, i princip för att fånga alla 401 unauthorized-svar från backend-servern (Rails) och logga ut användaren. Min förståelse hittills är att du måste instansiera axios en gång och använda den överallt, istället för att importera och använda en annan instans i varje fil.

Jag har hänvisat till detta och detta, och försökt nedanstående.

// application.js

import '../assets/sass/base.sass';
import App from '../app';
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import router from '../routes';

Vue.use(VueRouter);

document.addEventListener('DOMContentLoaded', () => {
  new Vue({
    el: '#application',
    router,
    render: (h) => h(App),
  });
});

axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response;
    if(status === 401) {
      // do stuff
    }
  }
);

Vue.prototype.$http = axios

När jag försökte anropa this.$http.put(...) i en annan fil, sa den att egenskapen $http inte finns (jag antar att det beror på att this i kontexten av den komponenten är själva komponenten, men jag är inte säker). Hur kan jag fixa detta?

[UPPDATERING] Tack vare svaren bestämde jag mig för att initiera en axios-instans i en separat fil och sedan använda den istället. Men detta fungerar fortfarande inte. 401-svaren verkar inte alls trigga interceptorn.

Behövs någon ytterligare konfiguration?

// axios-instance.ts
import axios, { AxiosInstance } from 'axios';

const axiosInstance: AxiosInstance = axios.create();

axiosInstance.interceptors.response.use(
  response => response.data,
  async function(error) {
    console.log("THIS IS THE 401 INTERCEPTOR")
    const status = error.response;
    if(status === 401) {
      // Log out user
    }
  }
);

export default axiosInstance;

// Some component
<script lang="ts">
import axiosInstance from 'axios-instance';

@Component
export default class ExamplePage extends Vue {
  created(): void {
    axiosInstance.post(some_path);
  }
}

Svar #1

Löser inte din fråga direkt, men sättet jag skapar en instans av axios är:

// axios-instance.js

import axios from 'axios'

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

export default instance

Efter att du precis har importerat instansen

// application.js

import axios from '../../axios-instance'

Svar #2

Du kan inte använda detta när du inte är i Vue-instansen. Prova detta:

// application.js

import '../assets/sass/base.sass';
import App from '../app';
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import router from '../routes';

Vue.use(VueRouter);

axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response;
    if(status === 401) {
      // do stuff
      }
    }
  }
);

Vue.prototype.$http = axios;

const VueInstance = new Vue({
    el: '#application',
    router,
    render: (h) => h(App),
});

Nu kan du göra HTTP-förfrågningar med this.$http:

<script>
    export default {
        methods: {
            doStuff() {
                this.$http.post('path_to_post_request').then(({ data }) => {
                    // do something with received data
                }).catch((e) => {});
            }
        }
    }
</script>

Relaterade artiklar