在公司内网环境访问外网必须要经过固定的代理服务器,本文介绍了内网开发会用到的一些代理配置方式,代理服务器的域名、IP 地址和端口假设为 proxy.example.com
、127.0.0.1
、8080
。
如何验证 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_proxy
或HTTPS_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 ignores no_proxy environment variable when proxy property set #5048
- 相关 PR feat(request): add noProxy setting for configuration (#5048) #5757
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;
微信开发者工具代理配置
如果系统设置过代理,则直接在【代理设置】中勾选【使用系统代理】;否则,选择【手动设置代理】,填入代理服务器地址和端口。
相关链接
- npm
- Yarn
- Java
- Gradle
- Maven
- PAC
- HTTP_PROXY, HTTPS_PROXY, NO_PROXY