正在显示
4 个修改的文件
包含
3 行增加
和
158 行删除
1 | -import fetch from 'dva/fetch'; | |
2 | -import { notification } from 'antd'; | |
3 | -import router from 'umi/router'; | |
4 | -import hash from 'hash.js'; | |
5 | -import { isAntdPro } from './utils'; | |
6 | - | |
7 | -const codeMessage = { | |
8 | - 200: '服务器成功返回请求的数据。', | |
9 | - 201: '新建或修改数据成功。', | |
10 | - 202: '一个请求已经进入后台排队(异步任务)。', | |
11 | - 204: '删除数据成功。', | |
12 | - 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', | |
13 | - 401: '用户没有权限(令牌、用户名、密码错误)。', | |
14 | - 403: '用户得到授权,但是访问是被禁止的。', | |
15 | - 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', | |
16 | - 406: '请求的格式不可得。', | |
17 | - 410: '请求的资源被永久删除,且不会再得到的。', | |
18 | - 422: '当创建一个对象时,发生一个验证错误。', | |
19 | - 500: '服务器发生错误,请检查服务器。', | |
20 | - 502: '网关错误。', | |
21 | - 503: '服务不可用,服务器暂时过载或维护。', | |
22 | - 504: '网关超时。', | |
23 | -}; | |
24 | - | |
25 | -const checkStatus = response => { | |
26 | - if (response.status >= 200 && response.status < 300) { | |
27 | - return response; | |
28 | - } | |
29 | - const errortext = codeMessage[response.status] || response.statusText; | |
30 | - notification.error({ | |
31 | - message: `请求错误 ${response.status}: ${response.url}`, | |
32 | - description: errortext, | |
33 | - }); | |
34 | - const error = new Error(errortext); | |
35 | - error.name = response.status; | |
36 | - error.response = response; | |
37 | - throw error; | |
38 | -}; | |
39 | - | |
40 | -const cachedSave = (response, hashcode) => { | |
41 | - /** | |
42 | - * Clone a response data and store it in sessionStorage | |
43 | - * Does not support data other than json, Cache only json | |
44 | - */ | |
45 | - const contentType = response.headers.get('Content-Type'); | |
46 | - if (contentType && contentType.match(/application\/json/i)) { | |
47 | - // All data is saved as text | |
48 | - response | |
49 | - .clone() | |
50 | - .text() | |
51 | - .then(content => { | |
52 | - sessionStorage.setItem(hashcode, content); | |
53 | - sessionStorage.setItem(`${hashcode}:timestamp`, Date.now()); | |
54 | - }); | |
55 | - } | |
56 | - return response; | |
57 | -}; | |
58 | - | |
59 | -/** | |
60 | - * Requests a URL, returning a promise. | |
61 | - * | |
62 | - * @param {string} url The URL we want to request | |
63 | - * @param {object} [option] The options we want to pass to "fetch" | |
64 | - * @return {object} An object containing either "data" or "err" | |
65 | - */ | |
66 | -export default function request(url, option) { | |
67 | - const options = { | |
68 | - expirys: isAntdPro(), | |
69 | - ...option, | |
70 | - }; | |
71 | - /** | |
72 | - * Produce fingerprints based on url and parameters | |
73 | - * Maybe url has the same parameters | |
74 | - */ | |
75 | - const fingerprint = url + (options.body ? JSON.stringify(options.body) : ''); | |
76 | - const hashcode = hash | |
77 | - .sha256() | |
78 | - .update(fingerprint) | |
79 | - .digest('hex'); | |
80 | - | |
81 | - const defaultOptions = { | |
82 | - credentials: 'include', | |
83 | - }; | |
84 | - const newOptions = { ...defaultOptions, ...options }; | |
85 | - if ( | |
86 | - newOptions.method === 'POST' || | |
87 | - newOptions.method === 'PUT' || | |
88 | - newOptions.method === 'DELETE' | |
89 | - ) { | |
90 | - if (!(newOptions.body instanceof FormData)) { | |
91 | - newOptions.headers = { | |
92 | - Accept: 'application/json', | |
93 | - 'Content-Type': 'application/json; charset=utf-8', | |
94 | - ...newOptions.headers, | |
95 | - }; | |
96 | - newOptions.body = JSON.stringify(newOptions.body); | |
97 | - } else { | |
98 | - // newOptions.body is FormData | |
99 | - newOptions.headers = { | |
100 | - Accept: 'application/json', | |
101 | - ...newOptions.headers, | |
102 | - }; | |
103 | - } | |
104 | - } | |
105 | - | |
106 | - const expirys = options.expirys && 60; | |
107 | - // options.expirys !== false, return the cache, | |
108 | - if (options.expirys !== false) { | |
109 | - const cached = sessionStorage.getItem(hashcode); | |
110 | - const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`); | |
111 | - if (cached !== null && whenCached !== null) { | |
112 | - const age = (Date.now() - whenCached) / 1000; | |
113 | - if (age < expirys) { | |
114 | - const response = new Response(new Blob([cached])); | |
115 | - return response.json(); | |
116 | - } | |
117 | - sessionStorage.removeItem(hashcode); | |
118 | - sessionStorage.removeItem(`${hashcode}:timestamp`); | |
119 | - } | |
120 | - } | |
121 | - return fetch(url, newOptions) | |
122 | - .then(checkStatus) | |
123 | - .then(response => cachedSave(response, hashcode)) | |
124 | - .then(response => { | |
125 | - // DELETE and 204 do not return data by default | |
126 | - // using .json will report an error. | |
127 | - if (newOptions.method === 'DELETE' || response.status === 204) { | |
128 | - return response.text(); | |
129 | - } | |
130 | - return response.json(); | |
131 | - }) | |
132 | - .catch(e => { | |
133 | - const status = e.name; | |
134 | - if (status === 401) { | |
135 | - // @HACK | |
136 | - /* eslint-disable no-underscore-dangle */ | |
137 | - window.g_app._store.dispatch({ | |
138 | - type: 'login/logout', | |
139 | - }); | |
140 | - return; | |
141 | - } | |
142 | - // environment should not be used | |
143 | - if (status === 403) { | |
144 | - router.push('/exception/403'); | |
145 | - return; | |
146 | - } | |
147 | - if (status <= 504 && status >= 500) { | |
148 | - router.push('/exception/500'); | |
149 | - return; | |
150 | - } | |
151 | - if (status >= 404 && status < 422) { | |
152 | - router.push('/exception/404'); | |
153 | - } | |
154 | - }); | |
155 | -} |
请
注册
或
登录
后发表评论