提交 e2cc6609 authored 作者: vipcxj's avatar vipcxj

improve: 从网络请求方法中抽象出中间件

上级 bb29d888
......@@ -9,3 +9,5 @@
# misc
.DS_Store
npm-debug.log*
/.idea
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{polyfill}" />
<file url="file://$PROJECT_DIR$" libraries="{app-web-client/node_modules}" />
<file url="PROJECT" libraries="{app-web-client/node_modules, polyfill}" />
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>
\ No newline at end of file
......@@ -3,9 +3,7 @@
<component name="JavaScriptSettings">
<option name="languageLevel" value="JSX" />
</component>
<component name="JsBowerSettings">
<node-interpreter value="project" />
<exe-path />
<config-path />
<component name="WebPackConfiguration">
<option name="path" value="" />
</component>
</project>
\ No newline at end of file
import _ from 'lodash';
/* eslint-disable no-param-reassign */
import { isNil, defaults } from 'lodash';
import { fetch } from './polyfill';
import { encrypt } from './helper';
import { errors } from './error';
import { getToken } from './auth';
import { checkStatus, normParams, parseObject } from './http-helper';
import middleware from './middleware';
const defaultOptions = {
headers: { Accept: 'application/json' },
......@@ -12,32 +11,25 @@ const defaultOptions = {
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {string} url The URL we want to delete
* @param auth
* @param params
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default async function doDelete(url, params = {}, options = {}, auth = true) {
let token;
if (auth) {
token = await getToken();
if (!token) {
return Promise.reject(errors.tokenMissing());
}
token = encrypt(token);
}
let queryParams = token ? [...normParams(params), ['token', token]] : normParams(params);
queryParams = queryParams.map(([k, v]) => (_.isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
params = normParams(params);
const res = await middleware.delete.onRequest(url, params, options, auth);
let queryParams = (res ? res.params : params).map(([k, v]) => (isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
queryParams = queryParams.join('&');
let realUrl = url;
let realUrl = res ? res.url : url;
if (queryParams) {
realUrl = `${url}?${queryParams}`;
}
const realOptions = _.defaults(options, defaultOptions);
const realOptions = defaults(res ? res.options : options, defaultOptions);
realOptions.method = 'DELETE';
return fetch(realUrl, realOptions)
.then(checkStatus)
.then(parseObject);
.then(resp => parseObject(resp, middleware.delete.onResponse));
}
......@@ -21,7 +21,7 @@ export function normParams(unnormed) {
}
// eslint-disable-next-line max-len
export function parseObject(response, { num2str = false, bool2str = false, nul2str = false, ud2str = false, nil2str = false } = {}) {
export function parseObject(response, middleware, { num2str = false, bool2str = false, nul2str = false, ud2str = false, nil2str = false } = {}) {
if (response.status === 204) { // no-content
return null;
} else {
......@@ -73,26 +73,32 @@ export function parseObject(response, { num2str = false, bool2str = false, nul2s
const mapValue = _.curry(mapObj)(_, mapArr);
if (contentType.indexOf('json') !== -1) {
return response.json()
.then((json) => {
if (json.errorCode === 0) {
let { data } = json;
if (_.isObjectLike(data)) {
data = new Resolver(data).resolve();
}
return needMap ? mapValue(data) : data;
} else {
throw new Error(json.message);
.then(json => (middleware ? middleware(json) : json))
.then((data) => {
let out = data;
if (_.isObjectLike(out)) {
out = new Resolver(out).resolve();
}
return needMap ? mapValue(out) : out;
});
} else if (contentType.indexOf('xml') !== -1) {
return response.text().then((text) => {
return require.ensure([], (require) => {
const { parseString } = require('xml2js');
const options = {};
const json = JSON.parse(parseString(text, options));
return needMap ? mapValue(json) : json;
return response.text()
.then((text) => {
return require.ensure([], (require) => {
const { parseString } = require('xml2js');
const options = {};
const json = JSON.parse(parseString(text, options));
return json;
});
})
.then((json => (middleware ? middleware(json) : json)))
.then((data) => {
let out = data;
if (_.isObjectLike(out)) {
out = new Resolver(out).resolve();
}
return needMap ? mapValue(out) : out;
});
});
} else if (contentType.indexOf('text') !== -1) {
return response.text();
} else {
......
/* eslint-disable no-unused-vars */
import { getToken } from './auth';
import { encrypt } from './helper';
import { errors } from './error';
const putTokenOnUrl = async (url, params, options) => {
let token = await getToken();
if (!token) {
throw errors.tokenMissing();
}
token = encrypt(token);
return {
url,
options,
params: [...params, ['token', token]],
};
};
const putTokenToBody = async (url, data, params, options) => {
let token = await getToken();
if (!token) {
throw errors.tokenMissing();
}
token = encrypt(token);
return {
url,
params,
options,
data: {
...data,
token,
},
};
};
const parseResponse = (response) => {
const { errorCode, data, message } = response;
if (errorCode === 0) {
return data;
} else {
throw new Error(message || data);
}
};
export default {
get: {
onRequest: async (url, params, options, auth) => {
if (auth) {
return putTokenOnUrl(url, params, options);
}
},
onResponse: parseResponse,
},
post: {
onRequest: async (url, data, params, options, auth) => {
if (auth) {
return putTokenToBody(url, data, params, options);
}
},
onResponse: parseResponse,
},
delete: {
onRequest: async (url, params, options, auth) => {
if (auth) {
return putTokenOnUrl(url, params, options);
}
},
onResponse: parseResponse,
},
};
/* eslint-disable no-param-reassign */
import _ from 'lodash';
import { isNil, defaults } from 'lodash';
import { fetch } from './polyfill';
import { encrypt } from './helper';
import { checkStatus, normParams, parseObject } from './http-helper';
import { getToken } from './auth';
import { errors } from './error';
import middleware from './middleware';
const defaultOptions = {
headers: {
......@@ -12,26 +10,20 @@ const defaultOptions = {
},
};
export default async function post(url, data, params = {}, options = {}, auth = true) {
if (!data) {
data = {};
}
if (auth) {
const token = await getToken();
if (!token) {
return Promise.reject(errors.tokenMissing());
}
data.token = encrypt(token);
}
let queryParams = normParams(params);
queryParams = queryParams.map(([k, v]) => (_.isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
params = normParams(params);
const res = await middleware.post.onRequest(url, data, params, options, auth);
let queryParams = res ? res.params : params;
queryParams = queryParams.map(([k, v]) => (isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
queryParams = queryParams.join('&');
let realUrl = url;
let realUrl = res ? res.url : url;
if (queryParams) {
realUrl = `${url}?${queryParams}`;
}
const realOptions = _.defaults(options, defaultOptions);
const realOptions = defaults(res ? res.options : options, defaultOptions);
if (!realOptions.headers) {
realOptions.headers = {
Accept: 'application/json',
......@@ -42,5 +34,5 @@ export default async function post(url, data, params = {}, options = {}, auth =
realOptions.body = JSON.stringify(data);
return fetch(realUrl, realOptions)
.then(checkStatus)
.then(parseObject);
.then(resp => parseObject(resp, middleware.post.onResponse));
}
import _ from 'lodash';
import { isNil, defaults } from 'lodash';
import { fetch } from './polyfill';
import { encrypt } from './helper';
import { getToken } from './auth';
import { errors } from './error';
import { checkStatus, normParams, parseObject } from './http-helper';
import middleware from './middleware';
const defaultOptions = {
headers: { Accept: 'application/json' },
......@@ -19,23 +17,19 @@ const defaultOptions = {
* @return {object} An object containing either "data" or "err"
*/
export default async function request(url, params = {}, options = {}, auth = true) {
let token;
if (auth) {
token = await getToken();
if (!token) {
return Promise.reject(errors.tokenMissing());
}
token = encrypt(token);
}
let queryParams = token ? [...normParams(params), ['token', token]] : normParams(params);
queryParams = queryParams.map(([k, v]) => (_.isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
const normedParams = normParams(params);
const res = await middleware.get.onRequest(url, normedParams, options, auth);
const newUrl = res ? res.url : url;
const newParams = res ? res.params : normedParams;
const newOptions = res ? res.options : options;
let queryParams = newParams.map(([k, v]) => (isNil(v) ? k : `${k}=${encodeURIComponent(v)}`));
queryParams = queryParams.join('&');
let realUrl = url;
let realUrl = newUrl;
if (queryParams) {
realUrl = `${url}?${queryParams}`;
}
return fetch(realUrl, _.defaults(options, defaultOptions))
return fetch(realUrl, defaults(newOptions, defaultOptions))
.then(checkStatus)
.then(parseObject);
.then(resp => parseObject(resp, middleware.get.onResponse));
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论