8. Data interaction axios

Data interaction axios

  • 1. Introduction to axios
  • 2. Basic syntax of axios
    • 2. 1 axios({})
    • 2. 2 axios.get(url,{})
    • 2. 3 axios.post(url,{})
  • 3. Basic cases
    • 3.1 Local call axios
    • 3. 2 Call axios globally
  • ==4. How to solve cross-domain problems==
    • 4. 1 Method 1 (simple)
    • 4.1 Method 2 (recommended)
  • ==5. Post parameter (request) format==
  • ==6. Interface Encapsulation==
    • ==6, 1 request/axios.js==
    • ==6, 2 request/api.js==
    • ==6, 3 use==
  • 7. Concurrency processing of axios (axios.all()) [Understand]
  • ==8. Interceptor==
    • 8.1 The difference between axios request interception and routing navigation guard

1. Introduction to axios

  • Official website: http://www.axios-js.com/
  • Kancloud: https://www.kancloud.cn/yunye/axios/234845 (document hosting platform, with detailed usage of axios)
  • Concept
     axios is an http library created based on Promise, which can be used on the client (browser) and node.js
     let p1 = new Promise((resolve,reject)=>{
         //Asynchronous code
         resolve(parameter),
         reject (error message)
     })
     p1.then((res)=>{
         console.log(res);//Successful callback, call resolve, and obtain the passed data through res
     }).catch((err)=>{
         console.log(err); //Failed callback, call reject, err error message
     })
    
    Official concept:
     Axios is a promise-based HTTP library that can be used in the browser and node.js
    
  • Features
    • Create XMLHttpRequests from the browser
    • Create http request from node.js
    • Support Promise API
    • Intercept requests and responses
    • Convert request data and response data
    • Cancel request
    • Automatically convert JSON data
    • Client Support Defense [XSRF]
     Cross-site request forgery (English: Cross-site request forgery), also known as one-click attack
     Or session riding, often abbreviated as CSRF or
     An attack method that performs unintended operations on an application. Compared with cross-site scripting (XSS), XSS takes advantage of the user's specific
     Website trust, CSRF takes advantage of the website's trust in the user's web browser.
    
  • Download (version 1 has problems and is unstable)
    npm i axios@0
    
    "axios": "^0.27.2
    

2. axios basic syntax

  • Introduce the axios library file, which will expose an ==axios() method. Under this method, there are two more: axios.get() and axios.post()== method

2, 1 axios({})

  • Similar to $.ajax(), you can initiate a get or post request and return a promise object
axios({
   url: 'The interface address you want to request',
   method: 'get/post', //default get// get parameters
   params: {
       //The input parameters of the get method request that you want to pass in
    },
   // post parameters
   data: {
      //The input parameters of the post request you want to pass in
   }
 }).then((res)=>{
     // The response res when successful, axios has a feature, the returned data contains a lot of configuration information
     // http status code is 200 or 304, the logic of successful execution (we are concerned about the res.code returned by the backend)
 }).catch((err)=>{
    //Response err when error occurs
    // The http status code is not 200 or 304, and the wrong logic is executed.
 })

2, 2 axios.get(url,{})

  • Similar to $.get(), initiate a get request. Note that the parameters passed are special
     axios.get('The interface address you want to request', {
         params: {
              //The input parameters of the get method request that you want to pass in, such as:
              a:1,
              b:2
         }
     }).then((res)=>{
          // The response res when successful, axios has a feature, the returned data contains a lot of configuration information
         //http status code is 200 or 304, the logic of successful execution
     }).catch((err)=>{
        //Response err when error occurs
        // The http status code is not 200 or 304, and the wrong logic is executed.
     })
    

2, 3 axios.post(url,{})

  • Similar to $.post(), initiate a post request
    axios.post('The interface address you want to request', {
      //The input parameters of the post request you want to pass in, such as:
       a:1,
       b:2
    }).then((res)=>{
      // The response res when successful, axios has a feature, the returned data contains a lot of configuration information
      //http status code is 200 or 304, the logic of successful execution
    }).catch((err)=>{
      //Response err when error occurs
      // The http status code is not 200 or 304, and the wrong logic is executed.
    })
    

    Except for data, which is returned by the real backend, everything else is configured by axios.

3. Basic case

3.1 Local call axios

  • code
<template>
  <div>
    <h1>this is axios--local use</h1>
    <ul>
      <li v-for="item in datalist" :key="item.id">{<!-- -->{<!-- --> item.name }}</li>
    </ul>
  </div>
</template>

<script>
//1. Download npm i axios@0
//2.Introduction (use it there, introduce it there - local)
import axios from "axios";
export default {<!-- -->
  data() {<!-- -->
    return {<!-- -->
      datalist: [],
    };
  },

  //Ajax requests can be initiated in created, beforeMount, and mounted. Generally, ajax requests are initiated in mounted.
  mounted() {<!-- -->
    //3. Request data axios({url,method,params:{}/data:{}})
    // axios({<!-- -->
    // url: "http://jsonplaceholder.typicode.com/comments", //Request address
    // method: "get", //Request method get and post, the default is get
    // params: { postId: 1 }, // get request with parameters, placed in params
    // })
    // .then((res) => {<!-- -->
    // //Request successful
    // console.log("Request successful");
    // //res will have a lot of configuration information, but the real data is in the data attribute
    // console.log(res.data);

    // //4. Request data, assign value, and render to page
    // this.datalist = res.data;
    // })
    // .catch((err) => {<!-- -->
    //     //Request failed
    // console.log("Request failed");
    // console.log(err); // Error message
    // });

    //4.axios.get(url,{params:{}})
    axios
      .get("http://jsonplaceholder.typicode.com/comments", {<!-- -->
        params: {<!-- -->
          postId: 1,
        },
      })
      .then((res) => {<!-- -->
        //Request successful
        console.log("Request successful");
        //res will have a lot of configuration information, but the real data is in the data attribute
        console.log(res.data);

        //4. Request data, assign value, and render to page
        this.datalist = res.data;
      })
      .catch((err) => {<!-- -->
        //Request failed
        console.log("Request failed");
      });
  },
};
</script>

<style>
</style>

3, 2 Call axios globally

  • code
    Defined as global in main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

//1. Globally introduce axios
import axios from "axios";
//2. Add to vue prototype
Vue.prototype.$axios = axios;

new Vue({<!-- -->
  router,
  render: h => h(App)
}).$mount('#app')

In the vue file of the case

<template>
 <div>
   <h1>this is axios -- for global use</h1>
   <ul>
     <li v-for="item in datalist" :key="item.id">{<!-- -->{<!-- --> item.name }}</li>
   </ul>
 </div>
</template>

<script>
//Basically all components may have data requests. If it is introduced once every time it is used, it will be troublesome.
//Define it as global
//1. Globally introduce axiox import axios from "axios";
//2. Add to vue prototype Vue.prototype.$axios = axios;
//3. Use in components
export default {<!-- -->
   data() {<!-- -->
   return {<!-- -->
     datalist: [],
   };
 },
 mounted() {<!-- -->
   this.$axios({<!-- -->
     url: "http://jsonplaceholder.typicode.com/comments", //Request address
     method: "get", //Request method get and post, the default is get
     params: {<!-- --> postId: 1 }, //get request with parameters, placed in params
   })
     .then((res) => {<!-- -->
       //Request successful
       console.log("Request successful");
       //res will have a lot of configuration information, but the real data is in the data attribute
       console.log(res.data);

       //4. Request data, assign value, and render to page
       this.datalist = res.data;
     })
     .catch((err) => {<!-- -->
       //Request failed
       console.log("Request failed");
       console.log(err); //error message
     });
 },
};
</script>

<style>
</style>

4. How to solve cross-domain problems

Note: Cross-domain issues in the development stage are handled by the front-end itself, while cross-domain backend issues in the production environment are handled by the front-end itself.

  • Vue configuration document: https://cli.vuejs.org/zh/config
  • Create a vue global configuration vue.config.js file (write the node syntax here), which must be at the same level as package.json to take effect.
  • Note: Once the configuration file is modified, the front end must be restarted

4.1 Method 1 (simple)

  • vue.config.js
// Export all the configuration files you encapsulated
module.exports = {<!-- -->
   // publicPath can configure its initial address according to your different environments. Generally it will not be modified and we will just '/'
   // outputDir output directory, used for packaging. Executing npm run build will generate the dist folder by default. If you want to change it to another folder name, just set the type directly.

   // devServer local development service configuration
   devServer:{<!-- -->
       //Set your proxy address (write the address of the backend server here)
       // When the front end accesses the server address in the future, write / directly in front of it.
       // The backend address was originally: http://localhost:3000/api/getbanner
       // Will be replaced by: http://localhost:8080/api/getbanner
       // This way there will be no cross-domain issues
       // proxy is proxy
       proxy: 'http://localhost:3000'
    }
  }
  • illustrate
    • Advantages: Simple configuration, just send it directly to the front end (8080) when requesting resources.
    • Disadvantages: Multiple proxies cannot be configured, and requests cannot be flexibly controlled whether to go through the proxy (if there are resources under the front-end public, the resources under the front-end’s own public will be used, that is, public is the root path)
    • Working method: : If the proxy is configured according to the above, when a resource that does not exist on the front end is requested, the request will be forwarded to the server (resources under public on the front end will be matched first)
  • Steps:
1.Configure vue.config.js
2. Please replace `http://localhost:3000/api/getbanner` with `/api/getbanner`
3. Restart the front end

If the configuration file is modified, the front end must be restarted

4.1 Method 2 (recommended)

  • vue.config.js
 module.exports = {<!-- -->
      devServer: {<!-- -->
         proxy: {<!-- -->
         '/api1': {<!-- --> // Match all request paths starting with '/api1'. Starting with /api1 means that the port is followed by /api1, and then the normal path is followed. /api1/api/getbanenr ==> /api/getbanenr
             target: 'http://localhost:3000', // The base path of the proxy target
             changeOrigin: true,
             secure: false, // By default, backend servers running over HTTPS with invalid certificates will not be accepted. If necessary, you can modify the configuration like this
             pathRewrite: {<!-- -->'^/api1': ''} // In the request address received by the backend, replace '/api1' with ''
             //api/getbanner
          },
          '/api2': {<!-- --> // Match all request paths starting with '/api2'
             target: 'http://localhost:3001', // The base path of the proxy target
             changeOrigin: true,
             pathRewrite: {<!-- -->'^/api2': ' '}
          }
       }
    }
 }
 /*
 When changeOrigin is set to true, the host in the request header received by the server is: localhost:3000 or 3001
 When changeOrigin is set to false, the host in the request header received by the server is: localhost:8080
 The default value of changeOrigin is true, and the default value in react is false
*/
  • illustrate
    • Advantages: Multiple proxies can be configured, and whether requests can be flexibly controlled through proxies
    • Disadvantages: The configuration is slightly cumbersome and you must add a prefix when requesting resources.
    • like
     module.exports = {<!-- -->
        devServer: {<!-- -->
          proxy: {<!-- -->
             '/ujiuye': {<!-- -->
              // Match all request paths starting with '/pzh'. Starting with /pzh means that the port is followed by /pzh, followed by the normal path.
              // This path will take the proxy: http://localhost:8080/ujiuye/api/getbanner
              //The actual content received by the backend is: http://localhost:3000/api/getbanner
              target: 'http://localhost:3000', // The base path of the proxy target
              changeOrigin: true,
              pathRewrite: {<!-- --> '^/ujiuye': '' }, // In the request address received by the backend, replace '/pzh' with ''
             },
          },
       },
     };
    
  • step:
1.Configure vue.config.js
2. Please replace `http://localhost:3000/api/getbanner` with `/pzh/api/getbanner`
3. Restart the front end

environmental judgment

let baseURL = ''; // base address

// Distinguish clearly whether it is a production environment or a development environment console.log(process.env.NODE_ENV); // Return the different identifiers of the development environment and the production environment
// development (development environment)
// production (production environment)

if (process.env.NODE_ENV === 'development') {
    // Development environment baseURL = '/pzh/api';
} else if (process.env.NODE_ENV === 'production') {
   //Production environment baseURL = 'http://localhost:3000/api';
}

5. Post parameter (request) format

  • There are mainly three types: distinguished according to Content-Type
  • For a mature backend, both the first and second types of reception should be set up. The third type of reception is to receive uploaded files.
  • Normal method (passing object) (request payload)
    Content-Type: application/json
    
    That is, data is transmitted in the form of objects. Or the json object string converted by JSON.stringify()
    
    {"phone":"155","password":"111"}
    
  • General form parameter passing (simulated form) (passing query string) (form-data) is more commonly used
    Note: It is a transmission method that does not upload files in the form format parameters
     Content-Type: application/x-www-form-urlencoded
      
     That is, the data is uploaded with 'a=1 & amp;b=2'
    
  • Form parameter passing (file passing) with uploaded files (use form-data to wrap data)
    https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
 Content-Type: multipart/form-data

You need to use the native FormData function to convert the data into this format (FormData is a container that packages uploaded data)

// Syntax
let file = new FormData(); // file is the data object
//Add data file.append('key','value')
// Get value data file.get('key')


==============================
// How to add the data in the object to FormData, you need to loop through it
let file = new FormData()
for(let attr in parameter object){
   file.append(attr, input parameter object [attr])
}
Summary:
The front end does not need to manually set the Content-Type, but the data format of the parameters is different, and the default Content-Type is also different.
 1. The common way is to pass in an object Content-Type: application/json
 
 2. Pass parameters in the general form, that is, pass in the query string (recommended) Content-Type: application/x-www-formurlencoded
 3. Pass the form parameters with the uploaded file, that is, pass the FormData object Content-Type: multipart/form-data
  • The third-party package qs performs data format conversion
    Thinking: Our data are generally objects, how to convert object data into query string format
    method one:
    Use querystring in native node.js method to convert
    
    querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' });
    // Return 'foo=bar & amp;baz=qux & amp;baz=quux & amp;corge='
    
    Method two:
    qs third-party package (in the vue scaffolding environment, the third-party package comes with it by default, you can just import it and use it without installing it)
    

6. Interface Encapsulation

  • Purpose: Classification, easy maintenance, and convenient management
  • Overview: The so-called interface encapsulation is to define a separate module specifically for managing http requests for the entire website, instead of writing requests in each component, which facilitates unified management.
  • Step
    1. Create the request folder under src
    2. There will be two files `axios.js` and `api.js` in the request folder.
    3.axios.js introduces the axios library and creates an http instance, api.js introduces the http instance in axios.js, and then other components introduce the methods defined in api.js
    

6, 1 request/axios.js

  • Function: This module is used to manage axios and set basic configurations (such as interceptors, etc.)
  • Note: There is no need to mount axios on the vue prototype.
  • Basic model
    import axios from 'axios'; //Introduce axios, so axios is not needed on the vue prototype
    
    let baseURL = ''; // base address
    if (process.env.NODE_ENV === 'development') {<!-- -->
       // development environment
       baseURL = '/ujiuye/api';
    } else if (process.env.NODE_ENV === 'production') {<!-- -->
       // Production Environment
       baseURL = 'http://localhost:3000/api';
    }
    
     //Call to create new instance
    let http = axios.create({<!-- -->
        //Here, define custom configuration for the current instance
        baseURL: baseURL // base address, which can uniformly manage your interface addresses
    });
    
    // Export new instance
    export default http;
    
  • Perfect model
    A more perfect way of writing: add request interception and response interception
    import axios from 'axios'; // Introduce axios, so axios is not needed on the prototype of Vue
    
    let baseURL = ''; // base address
    console.log(process.env.NODE_ENV); // Development environment and production environment
    
    if (process.env.NODE_ENV === 'development') {<!-- -->
       // Development environment requires cross-domain proxying
       baseURL = '/ujiuye/api';
     } else if (process.env.NODE_ENV === 'production')
       //Production environment, no cross-domain proxy required
       baseURL = 'http://localhost:3000/api';
     }
    
    //Call to create new instance
    let http = axios.create({<!-- -->
       //Here, define custom configuration for the current instance
       baseURL: baseURL // base address, which can uniformly manage your interface addresses
    });
    
    //Request to intercept interceptors interceptor
     http.interceptors.request.use((req) => {<!-- -->
           return req;
     });
     //Response to interception
     http.interceptors.response.use((res) => {<!-- -->
           return res;
     });
     
    // Export new instance
    export default http;
    

6, 2 request/api.js

  • Function: All requests are in this module, which is convenient for management without writing them in each component.
     import http from './axios'; // Introduce your encapsulated axios instance
     import qs from 'querystring'; //Introduce the querystring of the native node, and use the stringify method below to convert { foo: 'bar', corge: '123' } into 'foo=bar & amp;corge=123'. You can also use third-party packages
     
     //The following encapsulates a series of interfaces
    
     //Login interface, post mode, with parameters
     //The uploaded data format can be json or changed to query string. This is changed to a query string. This depends on the requirements of the back-end interface.
     export function login(data) {<!-- -->
        return http.post('/login',qs.stringify(data));
     }
     // Get the banner interface, get method, no parameters to be passed
     export function getBanner() {<!-- -->
        return http.get('/getbanner');
     }
     //Registration interface, post mode, with parameters
     export function register(data) {<!-- -->
        return http.post('/register',qs.stringify(data));
     }
    

6, 3 use

  • Introduce the required methods from request’s api.js and use them in a component
  • Use
     <template> in components
       <div>
          <!-- Title -->
          <v-title></v-title>
          <p>Phone: <input type="text" v-model='user.phone'></p>
          <p>Nickname: <input type="text" v-model='user.nickname'></p>
          <p>Password: <input type="text" v-model='user.password'></p>
    
         <p><button @click='goRegister'>Register</button></p>
       </div>
     </template>
    
     <script>
        import {<!-- -->register} from "@/request/api.js"
        export default {<!-- -->
           data(){<!-- -->
               return {<!-- -->
                  user:{<!-- -->
                     phone:"",
                     nickname:"",
                     password:""
                  }
             }
           },
         methods:{<!-- -->
            goRegister(){<!-- -->
               //1. Judgment, the content must be entered before execution can proceed.
               if(this.user.phone == "" || this.user.password == "" || this.user.nickname == ""){<!-- -->
                   alert("Please enter the necessary content");
                    return;
                }
    
              //2.Register
              // this.$axios.post("/ujiuye/api/register",this.user)
             register(this.user)
            .then(res=>{<!-- -->
                 if(res.data.code == 200){<!-- -->
                     alert(res.data.msg);
                     this.$router.push("/login")
                 }else{<!-- -->
                     alert(res.data.msg);
                 }
            }).catch(err=>{<!-- -->
               console.log(err);
            })
         }
      }
    }
    </script>
    
    <style scoped>
      p{<!-- -->
        line-height: .8rem;
        text-align: center;
      }
    </style>
    

7. Concurrent processing of axios (axios.all()) [Understand]

  • The so-called concurrency means that N interfaces can be called at the same time.
  • Method:
    axios.all([Request method 1(), Request method 2()])
    .then(res=>{ There are two requested data in res })
    .catch(err=>{ error })
    

Concurrent results can be spread using axios.spread(). The parameter of spread is a callback function, and the parameters of the callback function are the one-to-one corresponding results returned by concurrent calls.

  • Example
    //1. Introduce the axios library separately. Concurrency is used in a certain component. There is no all method on the encapsulated http.
     import axios from "axios";
    
    //2. Introduce encapsulated interfaces, here are two interfaces
    import {<!-- --> getHomeGoods, getHomeCate } from "../request/api;
    
    //3. Send a request
    axios
     .all([getHomeCate(), getHomeGoods()])
     .then(
        // spread expansion, it receives a function, the parameters of the function are the returned results
        //cate is the result of the first request, goods is the result of the second request
        axios.spread((cate, goods) => {<!-- -->
         // Process the first one
         if (cate.data.code == 200) {<!-- -->
              this.catelist = cate.data.list;
         } else {<!-- -->
              alert(cate.data.msg);
         }
         
        // Process the second one
        if (goods.data.code == 200) {<!-- -->
             this.hotslist = goods.data.list[0].content;
             this.newlist = goods.data.list[1].content;
             this.goodslist = goods.data.list[2].content;
        } else {<!-- -->
             alert(goods.data.msg);
        }
      })
     }
     // Unified handling of errors
     .catch(err => {<!-- -->
          console.log(err, "error");
      });
    

8. Interceptor

All written in request/axios.js

 import axios from 'axios'; //Introduce axios, so axios is not needed on the vue prototype

 // Call the method to create a new instance
 let http = axios.create({<!-- -->
      //Here, define custom configuration for the current instance
      baseURL: '/api' // Base address, which can uniformly manage your interface addresses
 });
  
  // Request interceptor: add attributes in req.headers, generally used to add tokens
  http.interceptors.request.use((req) => {<!-- -->
     // req.headers.pzh = 123; // req request header, add a request attribute in the request header, so you can see this request attribute in the requested network (generally used to add token)
     return req;
  });

  //Response interceptor: 1. Filter data 2. Determine whether the token has expired, etc.
  http.interceptors.response.use((res) => {<!-- -->
  // console.log(res.data); // That is the data returned by the backend
  // Usage 1. You can globally operate the returned data. For example, the data returned by the backend is packaged and always contains some unnecessary things, so we can only return what is needed.
  // return res.data;

  // 2. Global error judgment (key point) For example: the token expires. If it expires, we can let it log in again.

       return res;
  });

  //Export

 export default http;

8.1 The difference between axios request interception and routing navigation guard

Axios is triggered when an ajax request is initiated. It is generally used for adding tokens, global error handling, and filtering returned data.
Navigation guard is triggered when accessing a certain route. It is generally used to determine whether to log in, whether a certain user has the permission to access a certain route, etc.

The concept of token

  • Token means token. Where does the token come from? rear end
  • In fact, every interface that must be logged in to see the interface must verify the user name and password once, but every verification will put pressure on the server, so the concept of tokens was born.
  • The token is generated by the backend after the frontend logs in and is passed to the frontend. The frontend stores the token in local storage. When the front end wants to access certain interfaces that require login, bring it with you so that the back end only needs to verify the token instead of going to the database to verify the user name and password, which reduces the pressure on the back end.
  • The token will lose its validity, usually 3 to 5 minutes for important pages.