fetch.js封裝

npm install whatwg-fetch@3.0.0 --save --dev
npm install @babel/polyfill@7.4.4 --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<Response|never>}
 */
export function get (url, query, headers) {
  return fetch(
    'GET',
    convertUrl(url, query),
    undefined,
    headers
  );
}

/**
 * post請求
 * @param url
 * @param payload
 * @param headers
 * @returns {Promise<Response|never>}
 */
export function post (url, payload, headers) {
  return fetch(
    'POST',
    url,
    payload,
    headers
  );
}

/**
 * put請求
 * @param url
 * @param payload
 * @param headers
 * @returns {Promise<Response|never>}
 */
export function put (url, payload, headers) {
  return fetch(
    'PUT',
    url,
    payload,
    headers
  );
}

/**
 * delete請求
 * @param url
 * @param query
 * @param headers
 * @returns {Promise<Response|never>}
 */
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<any>}
 */
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')
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末盈包,一起剝皮案震驚了整個濱河市道川,隨后出現的幾起案子报破,更是在濱河造成了極大的恐慌跃须,老刑警劉巖蒙具,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件球榆,死亡現場離奇詭異,居然都是意外死亡禁筏,警方通過查閱死者的電腦和手機持钉,發(fā)現死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篱昔,“玉大人每强,你說我怎么就攤上這事≈莨簦” “怎么了空执?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穗椅。 經常有香客問我辨绊,道長,這世上最難降的妖魔是什么匹表? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任门坷,我火速辦了婚禮,結果婚禮上袍镀,老公的妹妹穿的比我還像新娘默蚌。我一直安慰自己,他們只是感情好苇羡,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布绸吸。 她就那樣靜靜地躺著,像睡著了一般设江。 火紅的嫁衣襯著肌膚如雪锦茁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天绣硝,我揣著相機與錄音蜻势,去河邊找鬼撑刺。 笑死鹉胖,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播甫菠,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼挠铲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寂诱?” 一聲冷哼從身側響起拂苹,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痰洒,沒想到半個月后瓢棒,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡丘喻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年脯宿,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泉粉。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡连霉,死狀恐怖,靈堂內的尸體忽然破棺而出嗡靡,到底是詐尸還是另有隱情跺撼,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布讨彼,位于F島的核電站歉井,受9級特大地震影響,放射性物質發(fā)生泄漏哈误。R本人自食惡果不足惜酣难,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望黑滴。 院中可真熱鬧憨募,春花似錦、人聲如沸袁辈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晚缩。三九已至尾膊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間荞彼,已是汗流浹背冈敛。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸣皂,地道東北人抓谴。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓暮蹂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親癌压。 傳聞我的和親對象是個殘疾皇子仰泻,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容