javascript - Vue projesinde axios'u global yapmak çalışmıyor


Şimdiye kadar, HTTP isteği yapmak istediğim her Vue bileşeninde axios'u şu şekilde içe aktarıyordum.

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

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

Ancak şimdi tüm axios istekleri için genel bir interceptor tanımlamak istiyorum, temel olarak backend sunucusundan (Rails) gelen tüm 401 yetkisiz yanıtları yakalamak ve kullanıcıyı çıkış yaptırmak için. Şu ana kadar anlayabildiğim kadarıyla, axios'u bir kez başlatmanız ve her yerde kullanmanız gerekiyor, her dosyada farklı bir örneği içe aktarıp kullanmak yerine.

Buna ve buna başvurdum ve aşağıdakileri denedim.

// 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

Başka bir dosyada this.$http.put(...) çağırmaya çalıştığımda, $http özelliğinin mevcut olmadığını söyledi (tahminimce bunun nedeni, o bileşenin bağlamında this'in bileşenin kendisi olması, fakat emin değilim). Bunu nasıl düzeltebilirim?

[GÜNCELLEME] Yanıtlar sayesinde, axios örneğini ayrı bir dosyada başlatmaya ve ardından onu kullanmaya karar verdim. Ancak, bu hâlâ çalışmıyor. 401 yanıtları, interceptor'ü hiç tetiklemiyor gibi görünüyor.

Ek bir yapılandırma gerekli mi?

// 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);
  }
}

Cevap #1

Sorunuzu doğrudan çözmüyor, ama axios örneğini oluşturma şeklim şöyle:

// 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

Örneği içe aktardıktan sonra

// application.js

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

Cevap #2

Vue örneğinde olmadığınızda bunu kullanamazsınız. Bunu deneyin:

// 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),
});

Artık this.$http kullanarak HTTP isteği yapabilirsiniz:

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

İlgili makaleler