我在用http event stream实现类似ChatGPT的打字机效果时遇到了这个问题:浏览器打开debug模式,看http event stream请求,EventStream直到最后一个消息发完才一直显示完所有消息。并不是请求失败,也不是没有响应,只是看起来像是卡住了,一直等到响应的数据全部接收完才一次性的回调onmessage方法。
没有什么是抓包分析不能解决的。
通过tcpdump抓包:
tcpdump -i any -w ./tcpdump3000.pcap 'tcp and port 3000'
然后使用ChatTCP工具分析。
上图为其中的一个event数据包的截图,可以看到,数据看着像是被加密处理过了。
但是我们没有做到任何的加密功能。唯一解释的通的,就是数据被压缩了。显示的配置关闭压缩后,再重新抓包分析。
可以看到,这次数据包正常了。
所以原因是请求开启了压缩功能,响应的body被压缩了,所以在body没有接收完的情况下,是无法解析body的。我们只需要关闭压缩功能即可,配置compress为false。
如果是Vue3项目这样配置:
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
// 解决http event stream卡到最后一个消息才一次性返回的问题。
compress: false,
proxy: {
'/api': {
target: 'http://localhost:8090',
changeOrigin: true
}
}
},
})
如果是next.js项目这样配置:
/** @type {import('next').NextConfig} */
const nextConfig = {
rewrites: async () => {
return [
{
source: '/api/:path*',
destination: process.env.PROXY_SERVER,
},
];
},
// 解决http event stream卡到最后一个消息才一次性返回的问题。
compress: false
}