This article only talks about encapsulation, does not involve download installation principle. All of the following wrapper code needs to be written in a file and exposed, and introduced in a file written to the API.

Creating an HTTP request

Create an instance using Axios:

const baseURL = ` /${process.env.VUE_APP_API_PREFIX}`; // Basic path of the interface

const http = axios.create({
  timeout: timeOut,
  withCredentials: true.headers: { 'X-Requested-With': 'XMLHttpRequest'.'X-CSRF-TOKEN': getToken() },
  baseURL
});
Copy the code

WithCredentials: true When cross-domain requests for I are initiated, CORS is enabled on the back end, and the front end also needs to carry cookies. In this case, this configuration needs to be added to the request header of the front end, indicating that the request can carry cookies.

Encapsulate GET and POST requests

export default{
  get(opts) {
    return new Promise((resolve, reject) = > {
      const params = {
        method: 'get'
      };
      http(merge(params, opts))
        .then(res= > {
          // This is the business logic request to get the res, usually contains data, code, MSG, res, etc
          resolve(res);
        })
        .catch(err= > {
          reject(err);
        });
    });
  },
  post(opts) {
    return new Promise((resolve, reject) = > {
      const params = {
        method: 'post'.headers: {
          'Content-Type': 'application/json'}}; http(merge(params, opts)) .then(res= > {
          // This is the business logic request to get the res, usually contains data, code, MSG, res, etc
          resolve(res);
        })
        .catch(err= >{ reject(err); }); }); }},Copy the code

Request server with wrapped GET and POST:

// Plain GET request
function getComponentByIdentification(params) {
  return http.get({
    url: `/web/system/getComponentByIdentification`,
    params
  });
}
// get file download, which is required to process the blob file after the request to the interface to create a tag for download
function downloadFile(params) {
  return http.get({
    url: '/web/protocol/download'.responseType: 'blob',
    params
  });
}
// A normal POST request
function saveOrUpdateProtocol(params) {
  return http.post({
    url: 'web/protocolManager/saveOrUpdateProtocol'.data: params
  });
}
Copy the code

usage

// Get and POST requests
const param = {
	protocolBaseInfo: this.protocolBaseInfo
};
getComponentByIdentification(param)
	.then(res= > {
    // Write business logic})// Write directly without passing the parameter
getComponentByIdentification()
    .then(res= > {
    // Write business logic
})
Copy the code

encapsulationdownloadDownload request. Different from GET and POST, download request needs to be compatible with IE and determine what type of file is downloaded.

The following code wraps the downloaded Excel file and wraps it if the download fails.

When the front end requests the server to download a file, it sends the file to the front end as a stream. The front end usually converts the stream to objectURL and downloads the file using the Download attribute of the A tag.

When the file download fails, the file format returned by the server is no longer a stream, but a JSON object (such as errorCode) returned by the server, but it is still wrapped in a Blob file. At this point, the Blob type is text/ JSON. But the file content is undefined.

It’s worth noting

If the download fails, the return type is text/json, but IE and Chrome both return the same, as follows:

The IE type is text/json. charset=utf-8″

Chrome for text/json

Res.type === ‘text/json’; Res.type.indexof (‘json’) > -1.

Therefore, the file contents need to be parsed

download(opts) {
    return new Promise((resolve, reject) = > {
      let newParams = {
        method: 'get'.responseType: 'blob'
      };
      newParams = merge(newParams, opts);
      http(newParams)
        .then(res= > {
          const blob = new Blob([res]);
          // Check whether the received file is json. If yes, error handling is required
          if (res.type.indexOf('json') > -1) {
            var newblob = blob.slice(0, blob.size);
             // We need to parse the JSON file wrapped inside the blob file
            var reader = new FileReader();
            reader.readAsText(newblob, 'utf-8');
            reader.onload = function(evt) {
              if (evt.target.readyState === FileReader.DONE) {
                const result = JSON.parse(evt.target.result);
                // The json object returned by result contains data, MSG, code, etc. (popup box, etc.)}}; }else {
            / / execl file
            const { params } = newParams;
            if (params.ext) params.type = params.ext;
            if (params.type === 'excel') params.type = 'xlsx';
            const fileName = `${params.fileName}.${params.type}`;
            if ('download' in document.createElement('a')) {
              // Non-IE download
              const elink = document.createElement('a');
              elink.download = fileName;
              elink.style.display = 'none';
              elink.href = URL.createObjectURL(blob);
              document.body.appendChild(elink);
              elink.click();
              URL.revokeObjectURL(elink.href); // Release the URL object
              document.body.removeChild(elink);
            } else {
              /** IE10+ download **/
              navigator.msSaveBlob(blob, fileName);
            }
          }
          resolve(res);
        })
        .catch(err= > {
          reject(err);
        });
    });
  }
Copy the code

Use this to download files:

// File download, request to the data does not need to do any processing, by the encapsulated download processing
function downloadFile(params) {
  return http.download({
    url: '/web/protocol/download',
    params
  });
}
Copy the code

Upload request encapsulation

upload(opts) {
    opts.url = `${opts.url}.do`;
    if(getToken() ! = =' ') {
      opts.url += `? _csrf=${getToken()}`;
    }
    const axiosUpload = axios.create({
      baseURL,
      timeout: timeOut,
      headers: {
        'Content-Type': 'multipart/form-data'.'X-Requested-With': 'XMLHttpRequest'}});// Response interceptor
    axiosUpload.interceptors.response.use(function(response) {
      // Uniformly handle errors
      return Promise.resolve(response.data);
    });
    return new Promise((resolve, reject) = > {
      axiosUpload
        .post(opts.url, opts.data)
        .then(res= > {
          resolve(res);
        })
        .catch(err= > {
          reject(err);
        });
    });
  },
Copy the code

The ‘X-requested-with ‘: ‘XMLHttpRequest’ here is to let the server know that this request is an Ajax request, to see if the component business needs to be set, and the company business needs to be used to connect With the single sign-on to other links.

Use this to upload documents

// File upload
function uploadFile(file) {
  return http.upload({
    url: `/web/protocolFile/upload`.data: file
  });
}

// When the interface is called
const form = new FormData();
// File object
form.append('file', file);
// Request method
uploadFile(form)
	.then(res= > {
    // Write business logic})Copy the code

The response to intercept

For response interception, ordinary GET and POST only need to pop up error boxes according to the error code. However, the upload and download interfaces need special treatment.

http.interceptors.response.use(
  function(response) {
    // The request file stream is downloaded using a GET request and the interface returns normal
    if (response.data.type === 'application/octet-stream') {
      // console.log(' file stream ');
      return response;
    }
      
    If the download interface uses a GET request, check whether it is an error
    // The blob file needs to be parsed and assigned to Response.data, which can be followed by the following error handling logic
    if (response.data.type && response.data.type.indexOf('json') > -1) {
      var reader = new FileReader();
      reader.addEventListener('loadend'.function(e) {
        response.data = JSON.parse(e.target.result);
      });
      reader.readAsText(response.data);
    }
      
    // Uniformly handle errors
    if(response.data.code ! = ='0') {
      console.log('cuowule!! ');
      // The background returns an error, which can be combined with some information of the business component to do some error processing
    }
    Response. data is the real data received after the interface request is completed. Then, excluding header and so on
    return Promise.resolve(response.data);
  },
  function(error) {
    const response = error.response;
    const rp = response.status;
   
    if (rp === 401 || rp === 403 || rp === 302) {
      if(process.env.NODE_ENV ! = ='development') {
        window.location.reload(); }}else {
      if (error.message.indexOf('timeout') > -1) {
        // To check the timeout, a dialog box must be displayed
      } else {
        // Interface error}}// Do something about the response error
    return Promise.reject(error); });Copy the code

Request to intercept

// Request interceptor
http.interceptors.request.use(function (config) {
  if (config.method === 'get') {
    config.url.indexOf('? ') > '1' ? 
        config.url = config.url + '& _ =' + Date.now() 
    	: config.url = config.url + '? _ = ' + Date.now()
  }
  return config
}, function (error) {
  // What to do about the request error
  return Promise.reject(error)
})
Copy the code