将开发代理用于Node.js应用程序

没有为 Node.js 应用程序启用代理的标准方法。 是否可以使用代理,取决于用于发出 HTTP 请求的库。 通常,需要更新代码来配置代理。 但是,可以使用包 global-agent 为Node.js应用程序启用代理支持,但代码更改最少。

本机Node.js提取 API

在 v17.5.0 中,Node.js引入了对 API 的 fetch 实验性支持。 遗憾的是,此 API 仍然受到限制,不支持配置代理。 如果要将开发代理用于Node.js,则需要使用不同的库发出 HTTP 请求。

global-agent

global-agent 是一个常用库,它提供用于Node.js的全局 HTTP/HTTPS 代理。 它允许你使用环境变量指定代理。 使用 global-agent 的好处是,无需更改在应用程序中发出 HTTP 请求以使用开发代理的方式。

下面是如何在使用Node.js应用程序中使用global-agentnode-fetch的示例:

import fetch from 'node-fetch';
import { bootstrap } from 'global-agent';
bootstrap();

(async () => {
  const result = await fetch('https://jsonplaceholder.typicode.com/posts');
  const jsonResult = await result.json();
  console.log(JSON.stringify(jsonResult, null, 2));
})();

下面介绍了如何与Node.js和标准https模块一起使用global-agent

const https = require('https');
const globalAgent = require('global-agent');
globalAgent.bootstrap();

https.get('https://jsonplaceholder.typicode.com/posts', (resp) => {
  let data = '';
  resp.on('data', (d) => {
    data += d;
  });
  resp.on('end', () => {
    console.log(JSON.parse(data));
  });
  resp.on('error', (err) => {
    console.error(err);
  });
});

启动应用程序时,使用 GLOBAL_AGENT_HTTP_PROXY 环境变量指定代理并忽略证书错误。

NODE_TLS_REJECT_UNAUTHORIZED=0 GLOBAL_AGENT_HTTP_PROXY=http://127.0.0.1:8000 node global-node-fetch.mjs

node-fetch

node-fetch 是一个常用的库,它提供 fetch 用于Node.js的实现。 node-fetch 不支持使用环境变量指定代理。 相反,你需要创建自定义代理并将其 fetch 传递给该方法。

下面是如何使用包定义代理https-proxy-agent来与开发代理一起使用node-fetch的示例。

const fetch = require('node-fetch');
const { HttpsProxyAgent } = require('https-proxy-agent');

(async () => {
  // Create a custom agent pointing to Dev Proxy
  const agent = new HttpsProxyAgent('http://127.0.0.1:8000');
  // Pass the agent to the fetch method
  const result = await fetch('https://jsonplaceholder.typicode.com/posts', { agent });
  const jsonResult = await result.json();
  console.log(JSON.stringify(jsonResult, null, 2));
})();

Axios

Axios 是另一个常用库,用于在 Node.js 中发出 HTTP 请求。 Axios 允许使用环境变量指定代理,或直接在请求配置中指定代理。

将 Axios 和开发代理与环境变量配合使用

将开发代理与 Axios 配合使用并使用环境变量指定代理时,无需更改代码。 只需设置环境变量, https_proxy Axios 会使用它发出请求。

import axios from 'axios';

(async () => {
  const result = await axios.get('https://jsonplaceholder.typicode.com/posts');
  const response = result.data;
  console.log(JSON.stringify(response, null, 2));
})();

https_proxy全局或启动应用时指定环境变量。

https_proxy=http://127.0.0.1:8000 node axios.mjs

类似于node-fetch,Got 不支持使用环境变量指定代理。 相反,你需要创建自定义代理并将其传递给请求。

下面是如何将 Got 与开发代理配合使用的示例:

import got from 'got';
import { HttpsProxyAgent } from 'https-proxy-agent';

(async () => {
  // Create a custom agent pointing to Dev Proxy
  const agent = new HttpsProxyAgent('http://127.0.0.1:8000');
  const result = await got('https://jsonplaceholder.typicode.com/posts', {
    // Pass the agent to the fetch method
    agent: {
      https: agent
    },
    // Disable certificate validation
    https: {
      rejectUnauthorized: false
    }
  }).json();
  console.log(JSON.stringify(result, null, 2));
})();

SuperAgent

SuperAgent 不支持使用环境变量指定代理。 若要将开发代理与 SuperAgent 配合使用,需要安装 superagent-proxy 插件并使用该方法配置代理 proxy

const superagent = require('superagent');
require('superagent-proxy')(superagent);

(async () => {
  const result = await superagent
    .get('https://jsonplaceholder.typicode.com/posts')
    .proxy('http://127.0.0.1:8000')
    // Disable certificate validation
    .disableTLSCerts();
  console.log(JSON.stringify(result.body, null, 2));
})();

已知问题

将开发代理用于Node.js时,可能会遇到以下问题。

UNABLE_TO_VERIFY_LEAF_SIGNATURE 个错误

将开发代理与Node.js配合使用时,会收到类似于以下内容的错误:

/Users/user/my-app/node_modules/node-fetch/lib/index.js:1501
                        reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
                               ^
FetchError: request to https://jsonplaceholder.typicode.com/posts failed, reason: unable to verify the first certificate
    at ClientRequest.<anonymous> (/Users/user/my-app/node_modules/node-fetch/lib/index.js:1501:11)
    at ClientRequest.emit (node:events:518:28)
    at TLSSocket.socketErrorListener (node:_http_client:495:9)
    at TLSSocket.emit (node:events:518:28)
    at emitErrorNT (node:internal/streams/destroy:169:8)
    at emitErrorCloseNT (node:internal/streams/destroy:128:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  type: 'system',
  errno: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
  code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
}

若要解决此问题,需要将 NODE_TLS_REJECT_UNAUTHORIZED 环境变量 0设置为 。 可以在启动应用时全局定义它,也可以进行内联定义。

NODE_TLS_REJECT_UNAUTHORIZED=0 node index.js