2
votes

I work in vue.js and I'm using the axios to make requests to the server. I have configured an interceptor to add authorizaton tokens to requests. Function which generates the token needs complete url with protocol to create the proper token. I have created my axios instance http. If I use complete url in http call: http.get('http://ediscore.net/api/config/category' it works well. But if I set the base URL at the axios level:const http = axios.create({baseURL: 'http://ediscore.net/api', and in axios call I use only http.get('config/category') I have a problem. The url from interceptor's property is not complete.


My interceptor:

http.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    console.log('Axios interceptor => config: ', config);
    console.log('Axios interceptor => config.url: ', config.url);
    const token: string = authService.getHmacToken(config.url, config.method);
    if (token) {
      config.headers.Authorization = `${token}`;
    }
    return config;
  },
  (error: AxiosError) => Promise.reject(error)
);

console.log() of the interceptor's config:

Axios interceptor => config:  {adapter: ƒ, transformRequest: {}, transformResponse: {}, timeout: 20000, xsrfCookieName: "XSRF-TOKEN"}
adapter: ƒ xhrAdapter(config)
baseURL: "http://ediscore.net/api"
data: undefined
headers: {Accept: "application/json", Authorization: ""...
maxContentLength: -1
method: "get"
timeout: 20000
transformRequest: {0: ƒ}
transformResponse: {0: ƒ}
url: "http://ediscore.net/api/config/category"
validateStatus: ƒ validateStatus(status)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
__proto__: Object

console.log() of the interceptor's config.url property:

Axios interceptor => config.url:  config/category

How is it possible that in the entire config object I can see property url: http://ediscore.net/api/config/category (complete, including protocol - see the line 11) but if I list only its property url, I get only config/category? (This is the value I send to the token generator and that's why it doesn't work because it's missing the baseURL part).

It makes no sense to me. Please help because I don't understand.

1
Reason for "console.log" showing different data is that browsers (chrome) evaluates values of an object just right in time when you expand it in the Console tab. Url of the config of interceptor is changed later in the code after http.interceptors.request.use is called.Reloecc
Well, it makes sense, but you can see two console.log() commands are following each other without any other action. How can I get the complete URL then? Always config.baseUrl + '/' + config.url?Ondrej Vencovsky
I answered that already.. config.url is String, so it's printed to console "as is". But the object is not printed into console, you see collapsed reference to object at first, and when you uncollapse it, it's loaded from memory in that time, not in the time of "console.log" is called. Run this command in the console: [ const object = { key: "value" }; console.log(object); object.key = "newvalue"; ] for testing purpose, uncollapse the object and you'll get what I meanReloecc

1 Answers

2
votes

You have to create an axios instance and then use that instance for interacting with the API.

For example create request.js

import axios from 'axios'

const request = axios.create({
  baseURL: 'https://your_api',
})

request.interceptors.request.use(
  request => {
    const token = localStorage.getItem('token')
    if (token) {
      request.headers.Authorization = token
    }
    return request
  },
  error => {
    return Promise.reject(error)
  }
)

export default request

Then in your components:

import request from './request.js'

export default {
  created() {
    request.get('/api_route')
      .then()
      .catch()
      .finally()
  }
}

Hope it helps.