我们使用egg去转发一些前端请求,原本使用curl去转发,但是做的过程中发现要用支持图片、excel等多种格式。尤其是excel格式,contentType改为'application/xml'之后是能下载,但是名字之类都不是想要的。试了下http-proxy-middleware,它对格式都进行了处理,但是它不支持koa和egg。想问下egg有没有类似的中间件
目前没有,可以参考 https://github.com/popomore/koa-proxy ,用 egg 的 curl 写一个类似的插件。
koa-proxy 这个有点 hack,慎用。
可以按照 http-proxy-middleware 自行实现
测试可行
const c2k = require('koa-connect');
const proxy = require('http-proxy-middleware');
module.exports = app => {
app.get('/api/v4/news/**', function* (next) {
yield c2k(proxy({ target: this.app.config.api.newApiUrl, changeOrigin: true }))(this, next);
});
};
@wangguohao app.get的路径调通了,但是post接口失败了,您能试一下吗?要怎么写?
请求到了服务端,但是出现了异常,我推断可能是body流被读过了
updated solution:
_proxy的代码要写在 bodyParser 前面_
@atian25,你好。。想请教一下用 curl 改写,如何把 cookie 塞进去呢?
ctx.curl(link, {
headers: {
cookie,
}
}
这样子好像不可以
curl 底层是 https://www.npmjs.com/package/urllib ,你可以研究下。
是不是你 cookie 的格式不对啥的,抓包看看。
@atian25 …… 多谢指点,是格式有点问题,后来直接把 header 全部塞进去就OK了。不过这就又有一个疑问想请教一下,如果想获取所有的 cookie 键值对,而 ctx.cookies 并不是一个可遍历对象,那就只能通过解析 header 里的 cookie 字符串了?
可以看下源码
也是。。不觉成了伸手党了。。
最近在写新项目,需要用 node 进行多个接口服务代理组合,针对代理可以通过以下方式解决
// app/middleware/httpProxy.js
const httpProxy = require('http-proxy-middleware');
const k2c = require('koa2-connect');
const pathToRegexp = require('path-to-regexp');
module.exports = (options) => {
const test1Proxy = k2c(httpProxy({
target: 'http://test1.com',
changeOrigin: true,
}));
const test2Proxy = k2c(httpProxy({
target: 'http://test1.com',
changeOrigin: true,
}));
return async function(ctx, next) {
if (pathToRegexp(/api\/v1/test1/).exec(ctx.request.url)) {
test1Proxy(ctx, next);
} else if (pathToRegexp(/api\/v1/test2/).exec(ctx.request.url)) {
test2Proxy(ctx, next);
} {
await next();
}
};
};
当然需要在 bodyparser 之前引入
// app.js
module.exports = app => {
app.config.coreMiddleware.unshift('httpProxy');
};
@wangguohao 可以封装成插件分享出来
@atian25 一般公司内部都会封装这样的包吧 阿里怎么没有开源
welcome to use koa2-proxy-middleware
@wangguohao app.get的路径调通了,但是post接口失败了,您能试一下吗?要怎么写?
请求到了服务端,但是出现了异常,我推断可能是body流被读过了
updated solution:
_proxy的代码要写在 bodyParser 前面_
@miaojiuchen 你好,post请求需要怎么请求呢? get请求是通得,post请求过不去????
@zheng199512 proxy的代码要写在 bodyParser 前面
app.use(c2k(httpProxy('/zheng', { target: 'http://www.icodehub.cn:7001', changeOrigin: true })));
写成这样是post和get请求都可以用的,这样写是符合规则的么?
我在想一个问题,两个月前有更新egg-proxy,能够按照match规则进行转发,貌似host和url是不能写多个的,有没有办法可以设置多个呢???请教一下~
@atian25 大佬,@miaojiuchen 大佬,
egg-proxy 并不是官方维护的插件,你可以去给作者提下 issue 交流下。https://github.com/xyeric/egg-proxy#readme
附上配置设置多个服务代理的方法,哇,藏的好深,感谢大佬的贡献,感谢大佬们的解答,谢谢,谢谢。https://github.com/xyeric/egg-proxy/issues/2
可以给对方 PR 更新到 README
请问下怎么对转发的请求添加参数呢?比如:加上 cookie
知道了,可以修改ctx.req.headers
需要去理解下 stream。
bodyParser 和 multipart 都会消费 ctx.req 这个 stream,所以你的 proxy 要不只能在它们之前,要不就配置下 ignore 掉。
但你在 proxy 里面又想校验,那就放到 bodyParser 和 multipart 之后,拿到它们已经消费好的东西,校验后,再自行传递到后面去。
@wangguohao 为啥要在bodyparser 之前引入,放在config里面的config.middleware = [
'httpProxy'
];
会有什么问题?
需要去理解下 stream。
bodyParser 和 multipart 都会消费 ctx.req 这个 stream,所以你的 proxy 要不只能在它们之前,要不就配置下 ignore 掉。
但你在 proxy 里面又想校验,那就放到 bodyParser 和 multipart 之后,拿到它们已经消费好的东西,校验后,再自行传递到后面去。
已经用这个方法实现了校验。原理就是每次消费后再将stream重新放入buffer。
const rawBody = ctx.request.rawBody;
if (rawBody) {
const buffer = new ReadableStream();
buffer.push(rawBody);
buffer.push(null);
proxy = k2c(
httpProxy(
Object.assign({}, options, {
buffer,
})
)
);
}
可以看下 egg-http-proxy-middleware
Most helpful comment
最近在写新项目,需要用 node 进行多个接口服务代理组合,针对代理可以通过以下方式解决
当然需要在 bodyparser 之前引入