umi-request icon indicating copy to clipboard operation
umi-request copied to clipboard

umi-request 在node.js中 使用response.json()返回的promise处于pending状态?

Open simpleman315 opened this issue 4 years ago • 11 comments

request.interceptors.response.use(async response => { const result = await response..json(); return Promise.resolve({ ...result, data: decrypt(result.data, secret) }); }); 代码如上,因为需要做ssr同构,node端直接采用了umi-request,使用过程中发现如果response中内容比较大的情况下,response..json()返回的promise对象处于pending状态,查看了源码发现使用了isomorphic-fetch库,而isomorphic-fetch库采用的是"node-fetch": "^1.0.1"版本的代码,在node-fetch1.x版本中的clone()方法代码如下: Body.prototype._clone = function(instance) { var p1, p2; var body = instance.body;

// don't allow cloning a used body
if (instance.bodyUsed) {
	throw new Error('cannot clone body after it is used');
}

// check that body is a stream and not form-data object
// note: we can't clone the form-data object without having it as a dependency
if (bodyStream(body) && typeof body.getBoundary !== 'function') {
	// tee instance body
	p1 = new PassThrough();
	p2 = new PassThrough();
	body.pipe(p1);
	body.pipe(p2);
	// set instance body to teed body and return the other teed body
	instance.body = p1;
	body = p2;
}

return body;

}

发现原因是代码使用了其中一个即 res.clone 的返回进行 .json 操作,相当于 p2.json()。但对另一个 res 即 p1 没有做处理。 而 stream 有一个 back pressure 机制,因为 p1 没有消耗,缓存数据满时会使其源 pause,从而导致 p2 也不能结束。

从上面跟踪发现应该是node-featch老版本的一个bug,发现node-fetch的最新版本已经修复了这个问题,但是umi-request引用了isomorphic-fetch库,这个库已经几年没更新,希望umi-request后续版本可以解决此问题!

simpleman315 avatar Apr 19 '20 14:04 simpleman315

感谢提出,当时基于支持 node 场景引入了 isomoriphic-fetch,目前看来由于 isomoriphic-fetch 没人维护,很多开发者都自行 fork 一份对 node-fetch 进行升级使用如 @applitools/isomorphic-fetch,而业界没有看到其他比较好的替代库,后续考虑前一种方案进行升级。

chenjsh36 avatar Apr 22 '20 08:04 chenjsh36

大佬能尽快解决这个issue吗? 我也遇到了 如果不能解决我只能找替代方案了...

luoweii avatar Dec 08 '20 09:12 luoweii

我们使用 Next.js 在服务端加载使用时,遇到了文件过大时,长时间处于请求状态,也是遇到了如此的问题。最后尝试使用了Next官方的Fetch方式,才定位到这个问题。希望umi可以解决吧。

yangtao2o avatar Mar 01 '21 10:03 yangtao2o

请问这个问题解决了吗?

yixiaoyan1 avatar May 20 '21 10:05 yixiaoyan1

我用的是umi的ssr,请求接口一致pending

yixiaoyan1 avatar May 20 '21 10:05 yixiaoyan1

Promise { <pending> }

遇到同样问题

FIGHTING-TOP avatar Sep 06 '21 03:09 FIGHTING-TOP

+1

lifegit avatar Sep 24 '21 10:09 lifegit

response中内容比较大的情况下,我这里大于30k就不行了。

lifegit avatar Sep 24 '21 10:09 lifegit

目前来说,isomorphic-fetch 作者已经升级到 3.0.0 。可以尝试 fork umi-request,修改 isomorphic-fetch 版本测试。

但我们找到了另外一个解决办法:node 版本使用 FROM node:14.16.1-stretch-slim 就可以了。以前我们用的 16.x 版本

lifegit avatar Sep 25 '21 03:09 lifegit

我这边问题解决了【umi 3 SSR】 在request.interceptors.response.use入参方法中去掉history的使用 可解决http请求正常返回问题

FIGHTING-TOP avatar Sep 26 '21 01:09 FIGHTING-TOP

跟node-fetch库提到的是同一个问题吗https://github.com/node-fetch/node-fetch/issues/1131 想问是否同样支持highWaterMark配置呢?

chenkuangkuang avatar Jun 28 '23 03:06 chenkuangkuang