fetch.js封装

npm install [email protected] --save --dev
npm install @babel/[email protected] --save --dev
main.js引入fetch垫片库

import '@babel/polyfill'; // babel, es6垫片库,ES6语法兼容IE等
import 'whatwg-fetch'; // fetch垫片库,支持IE等浏览器
import fetch from './lib/fetch';

/**
  Vue植入$get,$post等方法,并设置默认的请求头
  如果有额外的请求头请如下使用
  Vue.use(fetch[, fixedHeaders: object]);
*/
Vue.use(fetch);

fetch.js封装

import { Message } from 'element-ui';
import { getLocale, getUserId, getToken, urlStringify, getParam } from './util';
import service from '../service/';
import i18n from '@/i18n';
import {
  SERVICE_STATUS_SUCCESS,
  SERVICE_STATUS_TOKEN_FAILED,
  EN_LANG_ID,
  ZH_LANG_ID
} from '../constants'
const tips = {
  [ZH_LANG_ID]: {
    tokenError: i18n.t('tokenError'),
    requestError: i18n.t('requestError')
  },
  [EN_LANG_ID]: {
    tokenError: 'Auth error, please refresh the page',
    requestError: 'Request Error'
  }
}
const responseStatus200 = 200;
const mimeJSON = 'application/json';
const textPlain = 'text/plain';
let initHeader;

/**
 * 默认请求头
 */
let defaultHeaders = {
  'X-Emp-No': getUserId(),
  'X-Auth-Value': getToken()
};

export default {
  install (Vue, headers) {
    Vue.prototype.$get = get;
    Vue.prototype.$post = post;
    Vue.prototype.$put = put;
    Vue.prototype.$del = deleteHttp;
    Vue.prototype.$service = service;

    if (typeof headers === 'object') {
      initHeader = headers
    }
  }
};

/**
 * get请求
 * @param url
 * @param query
 * @param headers
 * @returns {Promise}
 */
export function get (url, query, headers) {
  return fetch(
    'GET',
    convertUrl(url, query),
    undefined,
    headers
  );
}

/**
 * post请求
 * @param url
 * @param payload
 * @param headers
 * @returns {Promise}
 */
export function post (url, payload, headers) {
  return fetch(
    'POST',
    url,
    payload,
    headers
  );
}

/**
 * put请求
 * @param url
 * @param payload
 * @param headers
 * @returns {Promise}
 */
export function put (url, payload, headers) {
  return fetch(
    'PUT',
    url,
    payload,
    headers
  );
}

/**
 * delete请求
 * @param url
 * @param query
 * @param headers
 * @returns {Promise}
 */
export function deleteHttp (url, query, headers) {
  return fetch(
    'DELETE',
    convertUrl(url, query),
    undefined,
    headers
  );
}

/**
 * 组合url
 * @param url
 * @param query
 * @returns {*}
 */
function convertUrl (url, query) {
  if (query) {
    let search;
    switch (typeof query) {
      case 'object':
        search = urlStringify(query);
        break;
      case 'string':
        search = query;
    }
    if (search) {
      url = [url, search].join(url.indexOf('?') === -1 ? '?' : '&');
    }
  }
  return url;
}

/**
 * 自定义fetch
 * @param method
 * @param url
 * @param body
 * @param headers
 * @returns {Promise}
 */
export function fetch (method, url, body, headers) {
  if (!url) {
    throw new Error('request url is empty!')
  }
  method = method.toUpperCase();
  // 组合header对象
  headers = headers || {};
  if ((method === 'POST' || method === 'PUT') && !(body instanceof FormData)) {
    headers['Content-Type'] = mimeJSON
    if (typeof body === 'object') {
      body = JSON.stringify(body);
    }
  }
  
  let locale = getLocale();
  headers = Object.assign({ 'X-Lang-Id': locale }, initHeader, headers, defaultHeaders);
  // fetch请求

  return new Promise((resolve, reject) => {
     window.fetch(url, {
      method,
      body,
      headers,
      cache: 'no-cache', // 缓存禁用
      mode: 'cors' // 是否支持跨域,可选 no-cors, cors, *same-origin
    }).then(Response => {
      if (Response.status !== responseStatus200) {
        Message({
          message: i18n.t('requestError'),
          type: 'error',
          center: true
        });
        reject(new Error('Response status error'));
        return;
      }
      let resContentType = Response.headers.get('content-type') || mimeJSON;
      if (resContentType.indexOf(mimeJSON) === 0 || resContentType.indexOf(textPlain) === 0) {
        Response.json().then(json => {
          try {
            resolve(responseJson(json, url, locale));
          } catch (e) {
            reject(json);
          }
        })
      } else if (resContentType.indexOf('text/') === 0) {
        Response.text().then(text => resolve(text))
      } else {
        Response.blob().then(blob => {
          resolve(responseBlob(blob, url))
        })
      }
    })
    .catch(() => {
      console.error('fetch catch')
      reject(new Error('fetch catch error'))
    })
  })
}

/**
 * 处理json
 * @param json
 * @param url
 * @param locale
 * @returns {*}
 */
function responseJson (json, url, locale) {
  switch (json.code.code) {
    case SERVICE_STATUS_SUCCESS:
      return json.bo;
    case SERVICE_STATUS_TOKEN_FAILED:
      toLogin();
      break;
    default:
      if (json.code.msg) {
        Message({
          message: json.code.msg,
          type: 'error',
          center: true
        });
      }
      throw new Error('fetch error:' + url);
  }
}

/**
 * 处理blob
 * @param blob
 * @param url
 * @returns {*}
 */
const filenameReg = /[^/]+$/;
const urlSplitReg = /[#?]/;
const illegalCharacter = /[?*:"<>/|]/g;
function responseBlob (blob, url) {
  return {
    blob,
    download (fileName) {
      if (!fileName) {
        let match = url.split(urlSplitReg)[0].match(filenameReg);
        if (!match) {
          fileName = 'unKnow'
        } else {
          fileName = match[0];
        }
      }
      return downloadBlob(blob, fileName.trim().replace(illegalCharacter, ''));
    }
  }
}

/**
 * 下载二进制blob
 * @param {blob} blob
 * @param {string} fileName 文件名
 */
function downloadBlob (blob, fileName) {
  // 兼容IE下载
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, fileName);
    return;
  }
  const URL = window.URL;
  if (!URL || !URL.createObjectURL) {
    throw new Error('error: not support download blob');
  }
  let a = document.createElement('a');
  let url = URL.createObjectURL(blob);
  a.setAttribute('href', url);
  a.setAttribute('download', fileName);
  a.click();
  URL.revokeObjectURL(url);
}

export function convertBatchProcessingResult(bo) {
  let successCount = parseInt(bo.success)
  let failCount = parseInt(bo.failed)
  return i18n.t('successProcessPrefix') + successCount + i18n.t('failProcessPrefix') + failCount + i18n.t('batchProcessAlertMsgSuffix')
}

你可能感兴趣的:(fetch.js封装)