Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

Encapsulation and usage of axios in Vue Typescript

August has arrived, and a mysterious opportunity has also come knocking. Carrying my luggage, I ran to Guangzhou alone to join a project started by a senior graduate. With a mix of uneasiness and excitement, I took my first step away from school.

Since I lived in a room in the office, my work life began as soon as I stepped out the door. I started working from five in the morning until nine at night. In the evenings, I worked on my own project, feeling tired but fulfilled. Every day, I also worried about losing hair and what to eat.

I sent a copy of the map of Huaguang that I wrote to my EO, but it was confiscated. It went online as a product for Starry Sky and required further improvement. 😟

I thought about adding a click event to each marker of every location on the map. When clicked, it would display a detailed introduction of that location. However, adding images for each place would make the file size too large if stored locally, which could cause lagging. So, I decided to store the images on a server instead. I re-read axios and learned how to package it by following some online tutorials. I also solved the cross-origin issue.

Packaging axios#

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'

const showStatus = (status: number) => {
  let message = ''
  switch (status) {
    case 400:
      message = 'Request Error (400)'
      break
    case 401:
      message = 'Unauthorized, please log in again (401)'
      break
    case 403:
      message = 'Access Denied (403)'
      break
    case 404:
      message = 'Request Error (404)'
      break
    case 408:
      message = 'Request Timeout (408)'
      break
    case 500:
      message = 'Server Error (500)'
      break
    case 501:
      message = 'Service Not Implemented (501)'
      break
    case 502:
      message = 'Network Error (502)'
      break
    case 503:
      message = 'Service Unavailable (503)'
      break
    case 504:
      message = 'Network Timeout (504)'
      break
    case 505:
      message = 'HTTP Version Not Supported (505)'
      break
    default:
      message = `Connection Error (${status})!`
  }
  return `${message}`
}

const service = axios.create({
  // Joint debugging
  baseURL: 'https://www.wanandroid.com',
  headers: {
    get: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
    },
    post: {
      'Content-Type': 'application/json;charset=utf-8'
    }
  },
  // Whether to control cross-site access requests
  withCredentials: true,
  timeout: 30000, // Timeout time
  transformRequest: [(data) => {
    data = JSON.stringify(data)
    return data
  }],
  validateStatus () {
    // Using async-await, handling reject cases is cumbersome, so resolve all and handle exceptions in business code
    return true
  },
  transformResponse: [(data) => {
    if (typeof data === 'string' && data.startsWith('{')) {
      data = JSON.parse(data)
    }
    return data
  }]
})

// Request interceptor
service.interceptors.request.use((config: AxiosRequestConfig) => {
    return config
}, (error) => {
    // Throw error to business code
    error.data = {}
    error.data.msg = 'Server Exception'
    return Promise.resolve(error)
})

// Response interceptor
service.interceptors.response.use((response: AxiosResponse) => {
    const status = response.status
    let msg = ''
    if (status < 200 || status >= 300) {
        // Handle http errors and throw to business code
        msg = showStatus(status)
        if (typeof response.data === 'string') {
            response.data = {msg}
        } else {
            response.data.msg = msg
        }
    }
    return response
}, (error) => {
    // Throw error to business code
    error.data = {}
    error.data.msg = 'Request Timeout or Server Exception'
    return Promise.resolve(error)
})

export default service

Usage#

@Component
export default class Home extends Vue{
  a = []
  getSomeThings(){
    return request({
        url: "/wxarticle/list/408/1/json",
        method:'get'
    }).then((response)=>{
      this.a = response.data.data.datas
      console.log(this.a)
    }).catch((error)=>{
      console.log(error)
    })
  }

 mounted(){
   this.getSomeThings()
 }

Solving Cross-Origin Issues#

Regarding what cross-origin is, we have already learned about it with AJAX. It is caused by the same-origin policy of browsers, which is a security measure imposed by browsers on JavaScript.

Approach to Solving Cross-Origin Issues with Axios#

We can configure a proxy server to request data from another server, then return the requested data to our proxy server, which will then return the data to our client. This way, we can achieve cross-origin access to data.

Configuring Proxy

Configure the following content in our vue.config.js file:

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'https://www.wanandroid.com',// The IP+port of the backend interface you want to request
                changeOrigin: true,// Allowing cross-origin, a virtual server will be created locally to send and receive data, so there will be no cross-origin issues between the server and the client
                ws: true,// Enable webSocket
                pathRewrite: {
                    '^/api': '',// Replace with the content in the target
                }
            }
        }
    }
}
Configuring baseURL

In our packaged axios file, change the baseURL to: '/api'

const service = axios.create({
  baseURL: '/api',

  …………

})

So, what do these two steps mean? Actually:

When we request '/wxarticle/list/408/1/json', it is equivalent to requesting: localhost:8080/api/wxarticle/list/408/1/json,
Then, the configured proxy intercepts '/api' and replaces it with the content of the target,
Therefore, the actual requested URL is https://www.wanandroid.com/wxarticle/list/408/1/json,
Thus, we have successfully accessed the interface we need.

Finally#

Now that we have understood it, let's get started,

What about the pictures from the school?

Ah? There are none.

What about the photography side? 😧

They...only have a few... 😧

Ah...this... 😩

In summary, the project is currently on hold 💢

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.