日常开发中用到的一些代理配置方式

在公司内网环境访问外网必须要经过固定的代理服务器,本文介绍了内网开发会用到的一些代理配置方式,代理服务器的域名、IP 地址和端口假设为 proxy.example.com127.0.0.18080

如何验证 HTTP 代理是否设置成功

首先无法使用 ping 命令,因为 ping 使用的是 ICMP 协议,不是 HTTP 协议。

类 Unix 系统可以使用 curl 测试是否可以访问外网:

$ curl https://www.baidu.com

Windows 可以使用 Invoke-WebRequest cmdlet 命令:

> Invoke-WebRequest -Uri https://www.baidu.com

# 可以通过 Get-Help 查看 Invoke-WebRequest 命令的帮助说明
> Get-Help Invoke-WebRequest

在命令行中使用代理

代理相关的环境变量,理论上不区分大小写,https_proxyHTTPS_PROXY 都可以生效,具体取决于程序实现。 如果希望配置多个三级域名不走代理,比如 a.example.com / b.example.com / c.example.com,除了将它们全部加入 no_proxy,还可以简化成二级域名 example.com(不支持 *.example.com 写法),更多细节参考 We need to talk: Can we standardize NO_PROXY?

sh-compatible Shell(适用于 macOS/Linux/WSL/Git Bash)

设置代理:

export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080
export all_proxy=http://proxy.example.com:8080
export no_proxy=localhost,127.0.0.1,example.com

如果希望配置持续生效,可以写入到 .bashrc/.zshrc 等文件中。

除了使用 proxy.example.com 域名,也可以使用对应 IP 地址:

export http_proxy=http://127.0.0.1:8080
export https_proxy=http://127.0.0.1:8080
export all_proxy=http://127.0.0.1:8080

取消代理:

unset http_proxy
unset https_proxy
unset all_proxy
unset no_proxy

Windows PowerShell

设置代理:

$env:http_proxy="http://proxy.example.com:8080"
$env:https_proxy="http://proxy.example.com:8080"
$env:no_proxy="localhost,127.0.0.1,example.com"

如果希望配置持续生效,可以将环境变量加入到系统环境变量中。

取消代理:

$env:http_proxy=""
$env:https_proxy=""
$env:no_proxy=""

Windows 命令提示符(cmd)

设置代理:

set http_proxy=http://proxy.example.com:8080
set https_proxy=http://proxy.example.com:8080
set no_proxy=localhost,127.0.0.1,example.com

取消代理:

set http_proxy=
set https_proxy=
set no_proxy=

npm 代理配置

设置代理:

npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080

设置成功后 .npmrc 会新增两条配置:

proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080

另外,公司内部部署了 npm 私服,地址形如 registry.npm.example.com,仅内网能访问,安装、发布私有包不应该走代理,因此需要加上 noproxy 配置:

npm config set noproxy registry.npm.example.com

相应地,.npmrc 的代理配置最终变成:

proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080
noproxy=localhost,registry.npm.example.com

这样便可以同时使用外网的 npm 官方源/淘宝源和内网的 npm 私服:

# 设置为 npm 官方源
npm config set registry https://registry.npmjs.org/
# 或者设置为淘宝源
npm config set registry https://registry.npm.taobao.org/

# `@example` 下的私有包始终使用内网 npm 源
npm config set @example:registry http://registry.npm.example.com/

再次推荐私有包命名为 @scope/name 形式,参见之前的文章 npm 私有包

取消代理:

npm config delete proxy
npm config delete https-proxy

Yarn 1.x 代理配置

设置代理,和 npm 类似:

yarn config set proxy http://proxy.example.com:8080
yarn config set https-proxy http://proxy.example.com:8080

# 如果 SSL 报错,可以禁用校验
yarn config set strict-ssl false
# 设置淘宝源
yarn config set registry https://registry.npm.taobao.org/

取消代理:

yarn config unset proxy
yarn config unset https-proxy

注意:Yarn 没有实现 noproxy,所以不存在 yarn config set noproxy registry.npm.example.com,其内部使用的请求库 request 只支持从环境变量 process.env.no_proxy 获取不走代理的 URL 配置,并且如果已经设置了 npm 或者 Yarn 的 proxy 配置项(Yarn 会默认读取 npm 配置),process.env.no_proxy 会被忽略。因此在代理配置时,如果需要排除某些地址,必须删除 npm 或者 Yarn 的代理配置,改为使用命令行环境变量。

Yarn 2 Berry 代理配置

设置代理:

yarn config set httpProxy http://proxy.example.com:8080
yarn config set httpsProxy http://proxy.example.com:8080

设置 npm registry 源:

yarn config set npmRegistryServer https://registry.npm.taobao.org/
yarn config set npmScopes.example.npmRegistryServer http://registry.npm.example.com/
yarn config set npmScopes.local.npmRegistryServer http://registry.npm.example.com/

如果使用了 HTTP 而非 HTTPS 的源,会报 Unsafe http requests must be explicitly whitelisted in your configuration 错误,可以将地址加入白名单:

macOS/Linux:

yarn config set unsafeHttpWhitelist --json '["*.example.com", "example.com"]'

在 Windows 命令行中输入 JSON 参数有所不同,需要对双引号进行转义:

Windows PowerShell:

yarn config set unsafeHttpWhitelist --json '[\"*.example.com\", \"example.com\"]'

# 如果不包含空格,外层的单引号可以省略
yarn config set unsafeHttpWhitelist --json [\"*.example.com\"]
yarn config set unsafeHttpWhitelist --json [\"*.example.com\",\"example.com\"]

Windows 命令提示符(cmd),字符串只支持双引号不支持单引号:

yarn config set unsafeHttpWhitelist --json "[\"*.example.com\", \"example.com\"]"

Git 代理配置

Git 仓库通常支持多个协议:

  • http:// 对应 http.proxy
  • https:// 对应 https.proxy
  • git:// 对应 core.gitproxy

如果通过 SSH 的方式访问 Git 仓库,则直接修改 SSH 配置。

设置全局代理:

git config --global http.proxy http://proxy.example.com:8080
git config --global https.proxy http://proxy.example.com:8080
git config --global core.gitproxy <自行参考 git 文档>

取消全局代理:

git config --global --unset http.proxy
git config --global --unset https.proxy
git config --global --unset core.gitproxy

如果只是希望某个项目设置代理,省略 --global 参数即可。

Gradle 代理配置

gradle.properties 中设置代理(可以是项目中的 gradle.properties 或者用户 HOME 目录的 .gradle/gradle.properties):

systemProp.http.proxyHost=proxy.example.com
systemProp.http.proxyPort=8080
systemProp.http.nonProxyHosts=localhost|127.0.0.1|10.*|*.example.com

systemProp.https.proxyHost=proxy.example.com
systemProp.https.proxyPort=8080
systemProp.https.nonProxyHosts=localhost|127.0.0.1|10.*|*.example.com

为了加速依赖下载,可能还需要设置镜像源:

在用户 HOME 目录的 .gradle 文件夹下创建 init.gradle 文件,即 ~/.gradle/init.gradle(Windows 环境下为 %USERPROFILE%\.gradle\init.gradle)。

allprojects {
    repositories {
        maven {
            url 'http://maven.example.com/content/groups/public'
            content {
                includeGroup "com.example"
            }
        }
        maven { url 'https://maven.aliyun.com/repository/public' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'https://maven.aliyun.com/repository/google' }
        mavenLocal()
        mavenCentral()
        jcenter()
        google()
        maven { url 'https://www.jitpack.io' }
    }
}

建议修改全局的 Gradle 配置,如果修改项目中的配置不一定生效,比如:

  • <React Native project>/android/build.gradle
  • <React Native project>/node_modules/react-native-screens/android/build.gradle
  • <React Native project>/node_modules/react-native-safe-area-context/android/build.gradle

Maven 代理配置

settings.xml 中设置代理:

<settings>
  <proxies>
    <proxy>
      <id>http-proxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.example.com</host>
      <port>8080</port>
      <nonProxyHosts>localhost|127.0.0.1|10.*|*.example.com</nonProxyHosts>
    </proxy>
    <proxy>
      <id>https-proxy</id>
      <active>true</active>
      <protocol>https</protocol>
      <host>proxy.example.com</host>
      <port>8080</port>
      <nonProxyHosts>localhost|127.0.0.1|10.*|*.example.com</nonProxyHosts>
    </proxy>
  </proxies>
</settings>

浏览器代理配置

手动代理配置

  • Windows:在 IE 中取消勾选【自动检测设置】和【使用自动配置脚本】,勾选【为 LAN 使用代理服务器】和【对于本地地址不使用代理服务器】,填入服务器地址和端口。
  • 手机:打开电脑热点,手机连接以后修改 WiFi 配置,选择【HTTP 代理-配置代理】,勾选【手动】,填入服务器地址和端口。

自动代理配置

  • Windows:在 IE 中勾选【使用自动配置脚本】,填入 PAC 文件地址。(不要勾选【自动检测设置】和【为 LAN 使用代理服务器】)
  • 手机:打开电脑热点,手机连接以后修改 WiFi 配置,选择【HTTP 代理-配置代理】,勾选【自动】,填入 PAC 文件地址。

自动代理配置依赖 PAC 文件,PAC 文件地址从何而来,见下文。

PAC 文件

PAC 即 Proxy Auto Config,最早由 Netscape Navigator 2.0 引入到 Web 浏览器中,大部分浏览器和操作系统都支持,以下是一段文件示例:

// proxy.pac
function FindProxyForURL(url, host) {
  if (dnsDomainIs(host, '.public.example.com')) {
    return 'PROXY 127.0.0.1:8080';
  }

  if (
    shExpMatch(host, 'localhost') ||
    shExpMatch(host, '127.0.0.1') ||
    shExpMatch(host, '10.*') ||
    shExpMatch(host, '192.168.*') ||
    shExpMatch(url, 'https://gitlab.example-inc.com/*') ||
    shExpMatch(url, 'https://oa.example-inc.com/*') ||
    shExpMatch(url, 'https://mail.example-inc.com/*') ||
    dnsDomainIs(host, '.example.com') ||
    dnsDomainIs(host, '.test.com')
  ) {
    return 'DIRECT';
  } else {
    return 'PROXY 127.0.0.1:8080';
  }
}

具体如何编写可以参考 Proxy Auto-Configuration (PAC) file - MDN

PAC 文件编写完成后需要托管到静态文件服务器上,以便通过某个地址访问,比如 http://static.example.com/proxy.pac

让 Nginx 支持 PAC 文件

Nginx 默认不支持 PAC 文件,直接将 proxy.pac 放到 Nginx 的 html 目录下,访问 http://static.example.com/proxy.pac 返回的媒体类型为 application/octet-stream,浏览器无法将其识别为代理配置文件。

需要手动修改 Nginx 的 mime.types 配置:

application/x-ns-proxy-autoconfig                pac;
# 或者
application/x-javascript-config                  pac;

至于默认返回的 application/octet-stream,取决于 Nginx 的 default_type 配置:

default_type  application/octet-stream;

微信开发者工具代理配置

如果系统设置过代理,则直接在【代理设置】中勾选【使用系统代理】;否则,选择【手动设置代理】,填入代理服务器地址和端口。

相关链接