Skip to content

Instantly share code, notes, and snippets.

@LeezQ
Created December 26, 2018 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeezQ/b1f7e67f96c7f61cda67d1f2be357722 to your computer and use it in GitHub Desktop.
Save LeezQ/b1f7e67f96c7f61cda67d1f2be357722 to your computer and use it in GitHub Desktop.
request
import fetch from 'dva/fetch';
import qs from 'qs';
import router from 'umi/router';
import { notification } from 'antd';
import message from 'antd/lib/message';
import getCookie from './getCookie';
const messages = {
'403Code': '返回码 403',
'403Message': '无接口访问权限,请咨询管理员。',
};
const check401 = res => {
return res; // 暂时始终返回 res
};
const check403 = res => {
// 配合权限SDK的403跳转
res
.json()
.then(jsonResult => {
if (jsonResult.code === '302' && jsonResult.location !== undefined) {
window.location.href = jsonResult.location;
}
})
.catch(() => {
notification.warning({
message: messages['403Code'],
description: messages['403Message'],
});
});
return res;
};
const check200 = (res, configs) => {
if (res.ok) {
return res.json().then(result => {
const messageContent = configs.messageParse(result);
const displayControl = configs.displayControl;
// 解析出业务 success
if (result.success) {
if (configs.successMsg) {
message.success(configs.successMsg);
}
} else {
const url = window.location.href.toString();
if (result.errorCode === '401') {
if (url.indexOf('/account/login') < 0) {
router.push(`/account/login?goto=${encodeURIComponent(url)}`);
}
return res; // 暂时始终返回 res
}
if (result.errorCode === '403') {
router.push('/403');
return res; // 暂时始终返回 res
}
switch (displayControl.type) {
case 'message':
message.error(messageContent.message, displayControl.duration);
break;
// throw messageContent.message;
default:
notification.error({
message: '出错了',
description: messageContent.message,
});
break;
// throw messageContent.message;
}
}
return result;
});
}
};
const errorMessages = res => {
return `${res.status} ${res.statusText}`;
};
const check404or50x = res => {
return new Promise(() => {
console.log(`${res.status}: ${res.statusText}`);
return;
});
};
const checkOtherCode = res => {
return new Promise((_, reject) => {
let err;
try {
res.json().then(jsonResult => {
err =
(jsonResult.reasons && jsonResult.reasons[0] && jsonResult.reasons[0].content) ||
errorMessages(res);
reject(err);
message.error(err);
});
} catch (e) {
err = errorMessages(res);
reject(err);
}
});
};
const beforeSend = newOptions => {
if (newOptions.method !== 'GET') {
newOptions.headers = {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
...newOptions.headers,
};
const contentType = newOptions.headers['Content-Type'];
if (contentType.indexOf('form-urlencoded') >= 0) {
newOptions.body = qs.stringify(newOptions.data || {});
// 如果 Content-Type 是json 的话,自动处理下 stringify
} else if (contentType.indexOf('json') >= 0) {
newOptions.body = JSON.stringify(newOptions.data || {});
} else if (contentType.indexOf('form-data') >= 0) {
// 如果不是 json,则删除 Content-Type ,让 浏览器自动添加,
// 不然 form-data 的 boundary 设置不上
// see more: https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post
delete newOptions.headers['Content-Type'];
}
}
return newOptions;
};
/**
* url 添加 ctoken
* @param {string} url
*/
const addUrlCtoken = url => {
let realURL = url;
const ctoken = getCookie('ctoken');
if (ctoken) {
const str = url.indexOf('?') > -1 ? '&' : '?';
realURL = `${url}${str}ctoken=${encodeURIComponent(ctoken)}`;
}
return realURL;
};
const commonFetch = (newUrl, newOptions, newConfigs) => {
return fetch(newUrl, newOptions).then(res => {
if (res.status === 401) {
// 401 未登录
return check401(res);
} else if (res.status === 403) {
// 403 无权限
return check403(res);
} else if (res.status === 404 || res.status >= 500) {
return check404or50x(res);
} else if (res.status === 200) {
return check200(res, newConfigs);
} else {
// 其他请求码
return checkOtherCode(res);
}
});
};
export interface IOptions {
method: string;
headers?: any;
params?: any;
body?: any;
data?: any;
}
const request = (url, options?: IOptions | any, configs = {}) => {
let newOptions = {
method: 'GET',
credentials: 'same-origin',
...options,
headers: options.headers || { Accept: 'application/json' },
data: options.body || options.params || options.data,
};
const newConfigs = {
ctoken: true,
messageParse: resJson => {
return {
success: typeof resJson.success !== 'undefined' ? resJson.success : true,
message: resJson.errorMsg || '',
};
},
displayControl: {
type: 'modal',
duration: 3,
},
...configs,
};
newOptions = beforeSend(newOptions);
let newUrl = url;
if ((newOptions.method === 'GET' || newOptions.method === 'DELETE') && options) {
delete newOptions.body;
newUrl += `?${qs.stringify(newOptions.data)}`;
}
if (newConfigs.ctoken) {
newUrl = addUrlCtoken(newUrl);
}
return commonFetch(newUrl, newOptions, newConfigs);
};
export default request;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment