From 569f1cd94dccba1f6096a0e802e7cbdd0d018d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B8=85?= Date: Mon, 1 Apr 2019 11:14:55 +0800 Subject: [PATCH] use umi-request (#3883) * use umi-request * use data repalce to body --- package.json | 68 +++++++++--------- src/services/api.js | 18 ++--- src/utils/request.js | 164 +++++++++++-------------------------------- 3 files changed, 84 insertions(+), 166 deletions(-) diff --git a/package.json b/package.json index 63c93b99..239197bf 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,34 @@ { "name": "ant-design-pro", "version": "2.3.0", - "description": "An out-of-box UI solution for enterprise applications", "private": true, + "description": "An out-of-box UI solution for enterprise applications", "scripts": { - "presite": "cd functions && npm install", - "start": "cross-env APP_TYPE=site umi dev", - "start:no-mock": "cross-env MOCK=none umi dev", - "build": "umi build", - "site": "npm run presite && cross-env APP_TYPE=site npm run build && firebase deploy && npm run docker:push", "analyze": "cross-env ANALYZE=1 umi build", - "lint:style": "stylelint 'src/**/*.less' --syntax less", - "lint:prettier": "check-prettier lint", + "build": "umi build", + "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", + "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", + "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", + "docker:build": "docker-compose -f ./docker/docker-compose.dev.yml build", + "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", + "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro", + "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", "lint": "eslint --ext .js src mock tests && npm run lint:style && npm run lint:prettier", - "lint:fix": "eslint --fix --ext .js src mock tests && stylelint --fix 'src/**/*.less' --syntax less", "lint-staged": "lint-staged", "lint-staged:js": "eslint --ext .js", - "tslint": "npm run tslint:fix", - "tslint:fix": "tslint --fix 'src/**/*.ts*'", + "lint:fix": "eslint --fix --ext .js src mock tests && stylelint --fix 'src/**/*.less' --syntax less", + "lint:prettier": "check-prettier lint", + "lint:style": "stylelint 'src/**/*.less' --syntax less", + "prettier": "node ./scripts/prettier.js", + "presite": "cd functions && npm install", + "site": "npm run presite && cross-env APP_TYPE=site npm run build && firebase deploy && npm run docker:push", + "start": "cross-env APP_TYPE=site umi dev", + "start:no-mock": "cross-env MOCK=none umi dev", "test": "umi test", - "test:component": "umi test ./src/components", "test:all": "node ./tests/run-tests.js", - "prettier": "node ./scripts/prettier.js", - "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", - "docker:build": "docker-compose -f ./docker/docker-compose.dev.yml build", - "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", - "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", - "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", - "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", - "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro" + "test:component": "umi test ./src/components", + "tslint": "npm run tslint:fix", + "tslint:fix": "tslint --fix 'src/**/*.ts*'" }, "dependencies": { "@antv/data-set": "^0.10.1", @@ -40,7 +40,6 @@ "dva": "^2.4.1", "enquire-js": "^0.2.1", "gg-editor": "^2.0.2", - "hash.js": "^1.1.7", "lodash": "^4.17.11", "lodash-decorators": "^6.0.1", "memoize-one": "^5.0.0", @@ -60,7 +59,8 @@ "react-fittext": "^1.0.0", "react-media": "^1.9.2", "umi": "^2.4.4", - "umi-plugin-react": "^1.7.2" + "umi-plugin-react": "^1.7.2", + "umi-request": "^1.0.5" }, "devDependencies": { "@types/history": "^4.7.2", @@ -107,16 +107,21 @@ "optionalDependencies": { "puppeteer": "^1.12.1" }, + "engines": { + "node": ">=8.0.0" + }, + "husky": { + "hooks": { + "pre-commit": "npm run lint-staged" + } + }, "lint-staged": { + "**/*.less": "stylelint --syntax less", + "**/*.{js,jsx}": "npm run lint-staged:js", "**/*.{js,ts,tsx,json,jsx,less}": [ "node ./scripts/lint-prettier.js", "git add" - ], - "**/*.{js,jsx}": "npm run lint-staged:js", - "**/*.less": "stylelint --syntax less" - }, - "engines": { - "node": ">=8.0.0" + ] }, "browserslist": [ "> 1%", @@ -129,10 +134,5 @@ "src/**/*.less", "config/**/*.js*", "scripts/**/*.js" - ], - "husky": { - "hooks": { - "pre-commit": "npm run lint-staged" - } - } + ] } diff --git a/src/services/api.js b/src/services/api.js index 6e789bcc..5358a8e1 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -16,7 +16,7 @@ export async function queryRule(params) { export async function removeRule(params) { return request('/api/rule', { method: 'POST', - body: { + data: { ...params, method: 'delete', }, @@ -26,7 +26,7 @@ export async function removeRule(params) { export async function addRule(params) { return request('/api/rule', { method: 'POST', - body: { + data: { ...params, method: 'post', }, @@ -36,7 +36,7 @@ export async function addRule(params) { export async function updateRule(params = {}) { return request(`/api/rule?${stringify(params.query)}`, { method: 'POST', - body: { + data: { ...params.body, method: 'update', }, @@ -46,7 +46,7 @@ export async function updateRule(params = {}) { export async function fakeSubmitForm(params) { return request('/api/forms', { method: 'POST', - body: params, + data: params, }); } @@ -74,7 +74,7 @@ export async function removeFakeList(params) { const { count = 5, ...restParams } = params; return request(`/api/fake_list?count=${count}`, { method: 'POST', - body: { + data: { ...restParams, method: 'delete', }, @@ -85,7 +85,7 @@ export async function addFakeList(params) { const { count = 5, ...restParams } = params; return request(`/api/fake_list?count=${count}`, { method: 'POST', - body: { + data: { ...restParams, method: 'post', }, @@ -96,7 +96,7 @@ export async function updateFakeList(params) { const { count = 5, ...restParams } = params; return request(`/api/fake_list?count=${count}`, { method: 'POST', - body: { + data: { ...restParams, method: 'update', }, @@ -106,14 +106,14 @@ export async function updateFakeList(params) { export async function fakeAccountLogin(params) { return request('/api/login/account', { method: 'POST', - body: params, + data: params, }); } export async function fakeRegister(params) { return request('/api/register', { method: 'POST', - body: params, + data: params, }); } diff --git a/src/utils/request.js b/src/utils/request.js index 398b787f..def290be 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -1,8 +1,10 @@ -import fetch from 'dva/fetch'; +/** + * request 网络请求工具 + * 更详细的api文档: https://bigfish.alipay.com/doc/api#request + */ +import { extend } from 'umi-request'; import { notification } from 'antd'; import router from 'umi/router'; -import hash from 'hash.js'; -import { isAntdPro } from './utils'; const codeMessage = { 200: '服务器成功返回请求的数据。', @@ -22,134 +24,50 @@ const codeMessage = { 504: '网关超时。', }; -const checkStatus = response => { - if (response.status >= 200 && response.status < 300) { - return response; - } +/** + * 异常处理程序 + */ +const errorHandler = error => { + const { response = {} } = error; const errortext = codeMessage[response.status] || response.statusText; + const { status, url } = response; + notification.error({ - message: `请求错误 ${response.status}: ${response.url}`, + message: `请求错误 ${status}: ${url}`, description: errortext, }); - const error = new Error(errortext); - error.name = response.status; - error.response = response; - throw error; -}; -const cachedSave = (response, hashcode) => { - /** - * Clone a response data and store it in sessionStorage - * Does not support data other than json, Cache only json - */ - const contentType = response.headers.get('Content-Type'); - if (contentType && contentType.match(/application\/json/i)) { - // All data is saved as text - response - .clone() - .text() - .then(content => { - sessionStorage.setItem(hashcode, content); - sessionStorage.setItem(`${hashcode}:timestamp`, Date.now()); - }); + if (status === 401) { + notification.error({ + message: '未登录或登录已过期,请重新登录。', + }); + // @HACK + /* eslint-disable no-underscore-dangle */ + window.g_app._store.dispatch({ + type: 'login/logout', + }); + return; + } + // environment should not be used + if (status === 403) { + router.push('/exception/403'); + return; + } + if (status <= 504 && status >= 500) { + router.push('/exception/500'); + return; + } + if (status >= 404 && status < 422) { + router.push('/exception/404'); } - return response; }; /** - * Requests a URL, returning a promise. - * - * @param {string} url The URL we want to request - * @param {object} [option] The options we want to pass to "fetch" - * @return {object} An object containing either "data" or "err" + * 配置request请求时的默认参数 */ -export default function request(url, option) { - const options = { - expirys: isAntdPro(), - ...option, - }; - /** - * Produce fingerprints based on url and parameters - * Maybe url has the same parameters - */ - const fingerprint = url + (options.body ? JSON.stringify(options.body) : ''); - const hashcode = hash - .sha256() - .update(fingerprint) - .digest('hex'); +const request = extend({ + errorHandler, // 默认错误处理 + credentials: 'include', // 默认请求是否带上cookie +}); - const defaultOptions = { - credentials: 'include', - }; - const newOptions = { ...defaultOptions, ...options }; - if ( - newOptions.method === 'POST' || - newOptions.method === 'PUT' || - newOptions.method === 'DELETE' - ) { - if (!(newOptions.body instanceof FormData)) { - newOptions.headers = { - Accept: 'application/json', - 'Content-Type': 'application/json; charset=utf-8', - ...newOptions.headers, - }; - newOptions.body = JSON.stringify(newOptions.body); - } else { - // newOptions.body is FormData - newOptions.headers = { - Accept: 'application/json', - ...newOptions.headers, - }; - } - } - - const expirys = options.expirys && 60; - // options.expirys !== false, return the cache, - if (options.expirys !== false) { - const cached = sessionStorage.getItem(hashcode); - const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`); - if (cached !== null && whenCached !== null) { - const age = (Date.now() - whenCached) / 1000; - if (age < expirys) { - const response = new Response(new Blob([cached])); - return response.json(); - } - sessionStorage.removeItem(hashcode); - sessionStorage.removeItem(`${hashcode}:timestamp`); - } - } - return fetch(url, newOptions) - .then(checkStatus) - .then(response => cachedSave(response, hashcode)) - .then(response => { - // DELETE and 204 do not return data by default - // using .json will report an error. - if (newOptions.method === 'DELETE' || response.status === 204) { - return response.text(); - } - return response.json(); - }) - .catch(e => { - const status = e.name; - if (status === 401) { - // @HACK - /* eslint-disable no-underscore-dangle */ - window.g_app._store.dispatch({ - type: 'login/logout', - }); - return; - } - // environment should not be used - if (status === 403) { - router.push('/exception/403'); - return; - } - if (status <= 504 && status >= 500) { - router.push('/exception/500'); - return; - } - if (status >= 404 && status < 422) { - router.push('/exception/404'); - } - }); -} +export default request; -- GitLab