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')
}