fix: 修复proxy丢失body和fallbackIndex影响proxy的bug

This commit is contained in:
万纯 2021-04-09 11:12:23 +08:00
parent d21c00a558
commit ba3016105d
6 changed files with 103 additions and 67 deletions

View File

@ -4,13 +4,17 @@ import historyFallback from 'connect-history-api-fallback';
const ASSET_EXTNAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg'];
export default () => (req, res, next) => {
if (req.path === '/favicon.ico') {
res.sendFile(join(__dirname, 'fes.png'));
} else if (ASSET_EXTNAMES.includes(extname(req.path))) {
next();
} else {
const history = historyFallback();
history(req, res, next);
export default api => (req, res, next) => {
const proxyConfig = api.config.proxy;
if (proxyConfig && Object.keys(proxyConfig).some(path => req.path.startsWith(path))) {
return next();
}
if (req.path === '/favicon.ico') {
return res.sendFile(join(__dirname, 'fes.png'));
}
if (ASSET_EXTNAMES.includes(extname(req.path))) {
return next();
}
const history = historyFallback();
history(req, res, next);
};

View File

@ -176,7 +176,7 @@ export default (api) => {
port,
proxy: api.config.proxy,
https: isHTTPS,
beforeMiddlewares: [...beforeMiddlewares, createRouteMiddleware()],
beforeMiddlewares: [...beforeMiddlewares, createRouteMiddleware(api)],
afterMiddlewares: [...middlewares],
customerDevServerConfig: api.config.devServer
});

View File

@ -0,0 +1,17 @@
export default (api) => {
api.describe({
key: 'exportStatic',
config: {
schema(joi) {
return joi.object({
htmlSuffix: joi.boolean(),
dynamicRoot: joi.boolean()
});
}
},
// TODO: api.EnableBy.config 读取的 userConfigmodifyDefaultConfig hook 修改后对这个判断不起效
enableBy: () => ('exportStatic' in api.userConfig
? api.userConfig.exportStatic
: api.config?.exportStatic)
});
};

View File

@ -45,7 +45,9 @@ export default (api) => {
val.forEach(callback);
}
if (lodash.isPlainObject(val)) {
Object.keys(val).forEach((key) => { callback(val[key], key); });
Object.keys(val).forEach((key) => {
callback(val[key], key);
});
}
}
@ -67,9 +69,12 @@ export default (api) => {
if (lodash.isPlainObject(newOption)) {
traversalHandler(newOption, (value, key) => {
if (key === 'headers') {
traversalHandler(newOption.headers, (headervalue, headerkey) => {
option.headers[headerkey] = newOption.headers[headerkey];
});
traversalHandler(
newOption.headers,
(headervalue, headerkey) => {
option.headers[headerkey] = newOption.headers[headerkey];
}
);
} else {
option[key] = newOption[key];
}
@ -102,11 +107,14 @@ export default (api) => {
// mock打开情况下配置的过滤前缀
const mockPrefixTemp = api.config.mock.prefix || mockPrefix;
mockPrefix = mockPrefixTemp === mockPrefix ? mockPrefixTemp : `${mockPrefixTemp}/`;
mockPrefix = mockPrefixTemp === mockPrefix
? mockPrefixTemp
: `${mockPrefixTemp}/`;
// mock文件处理
mockFile = parsePath('./mock.js');
if (!existsSync(mockFile)) {
api.logger.info('mock.js File does not exist, please check'); return;
api.logger.info('mock.js File does not exist, please check');
return;
}
// 清除require的缓存保证 mock 文件修改后拿到最新的 mock.js
if (require.cache[mockFile]) {
@ -119,7 +127,8 @@ export default (api) => {
const _initFunction = require(mockFile);
const initFunction = _initFunction.default || _initFunction;
if (!lodash.isFunction(initFunction)) {
api.logger.info('mock.js should export Function'); return;
api.logger.info('mock.js should export Function');
return;
}
initFunction({ cgiMock, mockjs, utils });
} catch (err) {
@ -132,65 +141,72 @@ export default (api) => {
return next();
}
// 请求以 cgiMock.prefix 开头,匹配处理
const matchRequet = requestList.find(item => req.path.search(item.url) !== -1);
const matchRequet = requestList.find(
item => req.path.search(item.url) !== -1
);
if (!matchRequet) {
return next();
}
// set header
res.set(matchRequet.headers);
// set Content-Type
matchRequet.type && res.type(matchRequet.type);
// set status code
res.status(matchRequet.statusCode);
// set cookie
traversalHandler(matchRequet.cookies, (item) => {
const name = item.name;
const value = item.value;
delete item.name;
delete item.value;
res.cookie(name, value, item);
});
const sendData = () => {
// set header
res.set(matchRequet.headers);
// set Content-Type
matchRequet.type && res.type(matchRequet.type);
// set status code
res.status(matchRequet.statusCode);
// set cookie
traversalHandler(matchRequet.cookies, (item) => {
const name = item.name;
const value = item.value;
delete item.name;
delete item.value;
res.cookie(name, value, item);
});
// do result
if (lodash.isFunction(matchRequet.result)) {
matchRequet.result(req, res);
} else if (
lodash.isArray(matchRequet.result) || lodash.isPlainObject(matchRequet.result)
) {
!matchRequet.type && res.type('json');
res.json(matchRequet.result);
} else {
!matchRequet.type && res.type('text');
res.send(matchRequet.result.toString());
}
// do result
if (lodash.isFunction(matchRequet.result)) {
matchRequet.result(req, res);
} else if (
lodash.isArray(matchRequet.result)
|| lodash.isPlainObject(matchRequet.result)
) {
!matchRequet.type && res.type('json');
res.json(matchRequet.result);
} else {
!matchRequet.type && res.type('text');
res.send(matchRequet.result.toString());
}
};
bodyParser.json({ strict: false })(req, res, () => {
bodyParser.urlencoded({ extended: true })(req, res, () => {
cookieParser()(req, res, () => {
sendData();
});
});
});
};
};
api.onStart(() => {
// 获取mock配置: 是否打开
mockFlag = lodash.isPlainObject(api.config.mock) ? true : api.config.mock;
mockFlag = lodash.isPlainObject(api.config.mock)
? true
: api.config.mock;
if (!mockFlag) return;
loadMock = createMock();
return chokidar.watch(mockFile, {
ignoreInitial: true
}).on('change', () => {
api.logger.info('mock.js changedreload');
loadMock = createMock();
});
return chokidar
.watch(mockFile, {
ignoreInitial: true
})
.on('change', () => {
api.logger.info('mock.js changedreload');
loadMock = createMock();
});
});
api.addBeforeMiddlewares(() => {
if (!mockFlag) return [];
return [
bodyParser.json(),
bodyParser.urlencoded({
extended: false
}),
cookieParser()
];
});
api.addBeforeMiddlewares(() => (req, res, next) => {
if (!mockFlag) return next();
loadMock(req, res, next);

View File

@ -4,11 +4,7 @@ export default (api) => {
key: 'proxy',
config: {
onChange: () => {
const server = api.getServer();
if (server) {
// refrest proxy service
server.setupProxy(api.config.proxy, true);
}
// todo 重新执行proxy的逻辑
},
schema(joi) {
return joi.object();

View File

@ -92,14 +92,17 @@ export default {
}).catch((err) => {
console.log(err);
});
request('/v2/movie/in_theaters_mock').then((data) => {
request('/v2/movie/in_theaters_mock', { a: 1 }, 'get').then((data) => {
console.log(data);
}).catch((err) => {
console.log(err);
});
console.log('测试 proxy!!');
request('/v2/movie/in_theaters_proxy').then((resp) => {
request('/v2/movie/in_theaters_proxy', { a: 1 }, {
method: 'get',
headers: { Accept: '*/*' }
}).then((resp) => {
console.log(resp);
}).catch((err) => {
console.log(err);