2023-11-26·9 min read
Node 18 Fetch 兼容与网络代理解决方案
Node.js 18 fetch 兼容性和网络代理配置的最终解决指南
Node.js网络
- centos7 无法安装node 18,因为一些c++依赖库的问题
- fetch是从node16开始支持,需要添加
NODE_OPTIONS='--experimental-fetch’来兼容支持
但是这个实验特性会有一些问题
- node-fetch库的兼容
// fetch-polyfill.js
import fetch, {
Blob,
blobFrom,
blobFromSync,
File,
fileFrom,
fileFromSync,
FormData,
Headers,
Request,
Response,
} from 'node-fetch'
if (!globalThis.fetch) {
globalThis.fetch = fetch
globalThis.Headers = Headers
globalThis.Request = Request
globalThis.Response = Response
}
// index.js
import './fetch-polyfill'
但是需要注意不同版本的node-fetch是不一样的
注意2.x ⇒ 3.x的区别
- 如何做proxy agent
http-proxy-agent只支持2.x的版本
可以搜具体怎么做
也就是3.x,如果node 18之后是不支持这样做的。
https://github.com/nodejs/node/issues/42814
类似https://www.npmjs.com/package/global-agent也是不完全支持3.x之后的版本的。
这里有很多抓包工具等,都提供了类似的方案,总之就是不行。
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
直接修改bash命令行也是不行,只能影响类似curl 等比较原始的请求命令
对于node原生发起的请求是不能进行代理的。
这里只讨论fetch,所以我也没试过axios等其他请求库是什么情况
- node 18的请求方法实现
在22年的某个版本后,实现是通过https://undici.nodejs.org/#/docs/api/Agent
undici这个请求库实现的。当然也是自己的。
里面提供了Agent的代理方法
这个全局代理的配置,会被node识别,所以最终的解决方法是:
import { setGlobalDispatcher, ProxyAgent } from 'undici';
const HTTP_PROXY = 'http://127.0.0.1:7890';
const proxyAgent = new ProxyAgent(HTTP_PROXY);
setGlobalDispatcher(proxyAgent);
如果不是node端,是使用2.x版本的node-fetch,或者浏览器原生,可以使用http-agent-proxy这个配置进行。
- 如果需要抓包https
这个全局证书安装之后,还需要在node端默认开启一个不安全的证书配置。
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
- 串行代理,场景是,我需要抓包,也需要翻墙。
代理工具大部分其实提供了“外部代理”的配置,可以搜索类似关键词看看
