在前后端分离的项目中,如果需要通过访问服务器,直接请求会引起跨域问题,这时我们需要使用 webpack 开发服务器中的代理来把特定的 URL 转发到后端服务器。
在代理 https 协议的地址时,又会因为 https 证书问题导致接口访问失败,报错 500!
先说解决方法:代理配置和 http 协议无其他差别,降低 node 版本到 11 以下,就能解决这个问题。
一、发现问题
我想要访问接口 https://172.16.255.241:4000/api/robot/suggest?query=q&use_rc=1&use_faq=1&use_mapping=1
, 于是我在项目中采取如下步骤(参考:代理到后端服务器)
- 在项目的 src/ 目录下创建一个 proxy.conf.json 文件
- 往这个代理配置文件中添加如下内容:
"/api": {
"target": "https://172.16.255.241:4000",
"secure": false,
"changeOrigin": true,
"logLevel": "debug"
}
- 在 CLI 配置文件 angular.json 中为 serve 目标添加 proxyConfig 选项:
...
"architect": {
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "your-application-name:build",
"proxyConfig": "src/proxy.conf.json"
},
...
4. 在 package.json 启动脚本中配置
...
"scripts": {
"ng": "ng",
"start": "ng --proxy-config proxy.conf.json",
},
...
- 使用
npm start
启动项目,调用接口时,报错 500
二、找到原因
当我发现这个问题后,运维同学说可能是 https 证书问题,于是他把 http 换成了 http 协议。我改了 proxy.conf.json 文件中代理配置?target,把 https 改为了 http ,于是请求正常,200。
网上去找解决方法,大家的解决方法都是我之前写的那样。于是让旁边同学看看,他新建了一个 ng 项目,和我同样的配置,发现能购正常访问。于是我也新建了一个项目,同样的配置,还是报错 500。
那就不是项目本身配置不对了,而是电脑配置或者其他 node、webpack 等配置不同导致。他用的 node v10.16.0,而我用的是 node v13.12.0。
三、解决问题
于是我切换 node 版本到 v10.16.0 就解决了500 错误的问题。(参考 mac 下的 node 管理工具:使用 nvm 管理不同版本的 node 与 npm)
在?如何修复升级 node 版本后的 eproto 错误 中解释道:
在 node.js 10 最小支持 TLS 版本是 TLSv1.0,但自从 v11.4.0, 是提高到 TLSv1.2。我怀疑 cidadao.sinesp.gov.br 的证书是用 TLSv1.0 签署的,它可以在 Node.js v10.15.3 上使用,但不能在 v12.2.0 上使用。
并且给出解决方法:
要使 Node.js 接受 TLSv1.0,可以使用 --ls-min-v1.0 选项来启动 Node.js 进程。
于是将?package.json 启动脚本中配置 start
...
"scripts": {
"ng": "ng",
"start": "node --tls-min-v1.0 node_modules/@angular/cli/bin/ng serve -o --proxy-config proxy.conf.json",
},
...
在换回 node v13.12.0 版本, 接口又可以正常访问了。
四、总结
当希望使用 https 协议地址代理到后端服务器时,你可以像使用 http 协议的地址一样配置好项目。然后使用以下任意一种方法解决非安全的 ssl 连接并且传输数据(https 证书不受信)。
- 降低 node.js 版本,如使用 node v10.16.0。
- 在 package.json 启动脚本中配置 start 为
node --tls-min-v1.0 node_modules/@angular/cli/bin/ng serve -o --proxy-config proxy.conf.json
另外,webpack 代理支持中国呢明确指出(参考:secure 配置)
默认情况下,使用无效证书运行在HTTPS上的后端服务器将不被接受。
在使用 https 协议时,secure 设置为 false。