代理是个啥
既然要聊反向代理, 那首先得知道代理是个啥吧? 嗯.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
正向代理
比如, 你买束花, 想要给隔壁工位的测试妹子小丽表白. 但是又怕被人家直面拒绝太没面子. 于是你把鲜花委托给平时和小丽一起的测试小伙伴小红. 让她帮忙把花送给小丽. 这就是一个简单的代理过程, 小红作为代理帮你把花送给了小丽, 当然这种情况在现实中并不推荐使用, 因为难以避免中间商赚差价文章源自联网快讯-https://x1995.cn/4565.html
在上面的例子中, 你作为客户端(请求方), 想要向服务方(小丽)发起请求. 但是碍于面子你主动找到了第三方(小红)作为代理向服务方发送请求, 这种情况就是常说的正向代理. 正向代理在互联网中的使用主要是科学上网, 你想访问谷歌但是碍于防火墙你只能通过vpn服务器作为代理才能访问. 这个时候一般也要找值得信赖的vpn厂商, 避免中间商赚差价文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
反向代理
关于反向代理的例子, 那就比较多啦. 比如, 孤独的你躺在床上夜不能寐. 于是乎, 拿出手机, 点亮了屏幕, 拨通 10086, 中国移动就会随机分配一个当前处于空闲的客服MM, 你可以和客服MM聊聊天, 问问她家住哪里, 有没有男朋友, 她的微信号, 她的手机号, 星座, 八字.......文章源自联网快讯-https://x1995.cn/4565.html
在这个例子中, 中国移动就充当了反向代理的角色. 你只需要拨打 10086. 至于会不会分配到 MM 会分配到哪个 MM 在接通之前你都是不知道的. 反向代理在互联网中的使用主要是实现负载均衡. 当你访问某个网站的时候, 反向代理服务器会从当前网站的所有服务器中选择一个空闲的服务器为你响应. 用于均衡每台服务器的负载率.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
修改 hosts 完成域名绑定
mac 用户直接执行 vim /private/etc/hosts 在 hosts 文件最后添加一行:文章源自联网快讯-https://x1995.cn/4565.html
127.0.0.1 a.com
这一句是什么意思呢? 就是告诉我们的电脑访问 a.com 的时候, 无需请求 DNS, 直接指向我们本机.文章源自联网快讯-https://x1995.cn/4565.html
ps: win 环境下, hosts 文件在 C:\Windows\System32\drivers\etc 文件夹下. 如果没有权限修改, 把 hosts 文件先拷贝到别的位置, 通过编辑器打开并添加最后一行内容以后再剪切到原来的位置替换即可.文章源自联网快讯-https://x1995.cn/4565.html
验证: 打开命令行窗口执行 ping a.com, 如果访问的 ip 为 127.0.0.1 说明我们的域名绑定就完成啦 ^_^文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
安装 nginx
要做 NGINX 反向代理, 肯定要安装 nginx, 本文安装步骤示例环境为 mac, win 的小伙伴, 可以百度一下嗷, 这个东西大同小异.文章源自联网快讯-https://x1995.cn/4565.html
- 安装 brew 命令, 执行 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- 安装 nginx, 执行 brew install nginx
- 启动 nginx nginx, 如果报没有权限, 执行 sudo nginx
nginx 启动后, 浏览器打开 localhost:8080, 即可验证. 出现以下界面说明安装成功.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
nginx 配置初探
配置完 hosts 域名已经能够成功绑定. 现在如果我们访问 a.com 实际上是会访问到我们的自己的电脑辣. 那还不抓紧试一下?文章源自联网快讯-https://x1995.cn/4565.html
浏览器访问 a.com文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
这是什么鬼????文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
为什么会 无法访问此网站 呢? 我们下载安装完 nginx 还没有做任何配置. 接下来, 我们稍微配置一下就 OK:文章源自联网快讯-https://x1995.cn/4565.html
- 命令行切换到 nginx 配置目录下 cd /usr/local/etc/nginx/servers
- 创建并编辑配置文件 vim test.conf, 在配置文件中粘贴以下内容
server {文章源自联网快讯-https://x1995.cn/4565.html
# 监听80端口号文章源自联网快讯-https://x1995.cn/4565.html
listen 80;文章源自联网快讯-https://x1995.cn/4565.html
# 监听访问的域名文章源自联网快讯-https://x1995.cn/4565.html
server_name a.com;文章源自联网快讯-https://x1995.cn/4565.html
# 根据访问路径配置文章源自联网快讯-https://x1995.cn/4565.html
location / {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 https://www.baidu.com文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass https://www.baidu.com;文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
- 保存文件, 并执行 nginx -s reload 重启 nginx.
- 回到浏览器, 打开 a.com 的页签, 强制刷新.
文章源自联网快讯-https://x1995.cn/4565.html
恭喜你已经完成了第一个 nginx 配置.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
创建跨域环境
通过一系列的折腾, 我们已经可以通过 nginx 将a.com 转发到百度. 完成了第一步, 接下来我们创建跨域的 Case 并一步一步通过 nginx 配置实现跨域.文章源自联网快讯-https://x1995.cn/4565.html
首先, 项目前后端添加 nginx 目录, 用户存放前后端代码. 代码结构如下图所示.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
其次编写前后端代码:文章源自联网快讯-https://x1995.cn/4565.html
前端代码(./fe/nginx/index.html):文章源自联网快讯-https://x1995.cn/4565.html
<!DOCTYPE html>文章源自联网快讯-https://x1995.cn/4565.html
<html lang="en">文章源自联网快讯-https://x1995.cn/4565.html
<head>文章源自联网快讯-https://x1995.cn/4565.html
<meta charset="UTF-8">文章源自联网快讯-https://x1995.cn/4565.html
<meta name="viewport" content="width=device-width, initial-scale=1.0">文章源自联网快讯-https://x1995.cn/4565.html
<meta http-equiv="X-UA-Compatible" content="ie=edge">文章源自联网快讯-https://x1995.cn/4565.html
<title>CORS 实现跨域</title>文章源自联网快讯-https://x1995.cn/4565.html
</head>文章源自联网快讯-https://x1995.cn/4565.html
<body>文章源自联网快讯-https://x1995.cn/4565.html
<h3>CORS 实现跨域</h3>文章源自联网快讯-https://x1995.cn/4565.html
<script>文章源自联网快讯-https://x1995.cn/4565.html
var xhr = new XMLHttpRequest()文章源自联网快讯-https://x1995.cn/4565.html
xhr.open('GET', 'http://localhost:8888/api/getFriend')文章源自联网快讯-https://x1995.cn/4565.html
xhr.setRequestHeader('token', 'quanquanbunengshuo')文章源自联网快讯-https://x1995.cn/4565.html
xhr.withCredentials = true;文章源自联网快讯-https://x1995.cn/4565.html
xhr.onreadystatechange = function() {文章源自联网快讯-https://x1995.cn/4565.html
if(xhr.readyState === 4 && xhr.status === 200) {文章源自联网快讯-https://x1995.cn/4565.html
console.log(xhr.responseText)文章源自联网快讯-https://x1995.cn/4565.html
console.log(xhr.getAllResponseHeaders())文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
xhr.send()文章源自联网快讯-https://x1995.cn/4565.html
</script>文章源自联网快讯-https://x1995.cn/4565.html
</body>文章源自联网快讯-https://x1995.cn/4565.html
</html>文章源自联网快讯-https://x1995.cn/4565.html
编写完前端代码以后, 启动前端 web 容器. live-server ./fe/nginx文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
命令行中出现了黄色警告, 通知我们 8080 端口已经被占用, 这又是为什么呢? 大家请思考一哈.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
我们重新指定一个端口live-server ./fe/nginx --port=9999 哈哈, 换一个指令, 依旧是那么顺畅. ^_^文章源自联网快讯-https://x1995.cn/4565.html
后端代码:文章源自联网快讯-https://x1995.cn/4565.html
const http = require('http');文章源自联网快讯-https://x1995.cn/4565.html
const PORT = 8888;文章源自联网快讯-https://x1995.cn/4565.html
// 创建一个 http 服务文章源自联网快讯-https://x1995.cn/4565.html
const server = http.createServer((request, response) => {文章源自联网快讯-https://x1995.cn/4565.html
console.log(request.headers)文章源自联网快讯-https://x1995.cn/4565.html
response.end("{name: 'quanquan', friend: 'guiling'}");文章源自联网快讯-https://x1995.cn/4565.html
});文章源自联网快讯-https://x1995.cn/4565.html
// 启动服务, 监听端口文章源自联网快讯-https://x1995.cn/4565.html
server.listen(PORT, () => {文章源自联网快讯-https://x1995.cn/4565.html
console.log('服务启动成功, 正在监听: ', PORT);文章源自联网快讯-https://x1995.cn/4565.html
});文章源自联网快讯-https://x1995.cn/4565.html
启动后端服务 node ./be/nginx/index.js文章源自联网快讯-https://x1995.cn/4565.html
完善 nginx 配置
前后端代码已经准备完成, 这一步我们就来点干货. 完成最后的配置.文章源自联网快讯-https://x1995.cn/4565.html
- 首先, 修改 nginx 配置, 把百度地址替换成本地的前端地址
server {文章源自联网快讯-https://x1995.cn/4565.html
# 监听80端口号文章源自联网快讯-https://x1995.cn/4565.html
listen 80;文章源自联网快讯-https://x1995.cn/4565.html
# 监听访问的域名文章源自联网快讯-https://x1995.cn/4565.html
server_name a.com;文章源自联网快讯-https://x1995.cn/4565.html
# 根据访问路径配置文章源自联网快讯-https://x1995.cn/4565.html
location / {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 http://127.0.0.1:9999文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass http://127.0.0.1:9999;文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
- 修改完成 nginx 配置文件以后, 切记执行 nginx -s -reload 重启 nginx.
- 访问a.com
文章源自联网快讯-https://x1995.cn/4565.html
熟悉的报错又出现了...文章源自联网快讯-https://x1995.cn/4565.html
- 修改前端项目中的接口地址
// 接口地址修改为当前域名下 /api 路劲下的 getFriend
xhr.open('GET', '/api/getFriend')
- 修改 nginx 配置文件
server {文章源自联网快讯-https://x1995.cn/4565.html
# 监听80端口号文章源自联网快讯-https://x1995.cn/4565.html
listen 80;文章源自联网快讯-https://x1995.cn/4565.html
# 监听访问的域名文章源自联网快讯-https://x1995.cn/4565.html
server_name a.com;文章源自联网快讯-https://x1995.cn/4565.html
# 根据访问路径配置文章源自联网快讯-https://x1995.cn/4565.html
location / {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 http://127.0.0.1:9999文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass http://127.0.0.1:9999;文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
# 监听根目录下的 /api 路径文章源自联网快讯-https://x1995.cn/4565.html
location /api/ {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 http://127.0.0.1:8888文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass http://127.0.0.1:8888;文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
新加的对于 api 路径的监听的意思就是把关于后端 api 的请求转发到后端项目上(哈哈, 当然这就是为啥好多后端接口都是要有 /api 开头的啦). 重启 nginx 以后, 再次刷新浏览器, 后端返回的结果已经成功的打印到了控制台, 本次跨域访问任务完成.文章源自联网快讯-https://x1995.cn/4565.html
文章源自联网快讯-https://x1995.cn/4565.html
细心的小伙伴肯定发现了, 控制台还有一个报错. 这个是因为我们的项目中用到了 live-server 这个工具需要 websocket 导致的. 我们可以通过添加以下配置解决.文章源自联网快讯-https://x1995.cn/4565.html
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
文章源自联网快讯-https://x1995.cn/4565.html
报错消失, 此时完整的 nginx 配置文件为文章源自联网快讯-https://x1995.cn/4565.html
server {文章源自联网快讯-https://x1995.cn/4565.html
# 监听80端口号文章源自联网快讯-https://x1995.cn/4565.html
listen 80;文章源自联网快讯-https://x1995.cn/4565.html
# 监听访问的域名文章源自联网快讯-https://x1995.cn/4565.html
server_name a.com;文章源自联网快讯-https://x1995.cn/4565.html
# 根据访问路径配置文章源自联网快讯-https://x1995.cn/4565.html
location / {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 http://127.0.0.1:9999文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass http://127.0.0.1:9999;文章源自联网快讯-https://x1995.cn/4565.html
# 兼容websocket文章源自联网快讯-https://x1995.cn/4565.html
proxy_http_version 1.1;文章源自联网快讯-https://x1995.cn/4565.html
proxy_set_header Upgrade $http_upgrade;文章源自联网快讯-https://x1995.cn/4565.html
proxy_set_header Connection "upgrade";文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
# 监听根目录下的 /api 路径文章源自联网快讯-https://x1995.cn/4565.html
location /api/ {文章源自联网快讯-https://x1995.cn/4565.html
# 把请求转发到 http://127.0.0.1:8888文章源自联网快讯-https://x1995.cn/4565.html
proxy_pass http://localhost:8888;文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
}文章源自联网快讯-https://x1995.cn/4565.html
前后端代码地址为: https://github.com/luoquanquan/cross-domain/commit/f38f56689fdac1526244ecadaa979a52c9c4a7ea文章源自联网快讯-https://x1995.cn/4565.html
总结
至此, 我们已经通过 nginx 反向代理的方式实现了跨域访问 api, 在系列文章第一篇( https://juejin.im/post/5c07fa04e51d451de968906b )对于跨域的解释为: 跨域源于同源策略, 是浏览器保证用户安全的行为. 我们使用的 nginx 反向代理实际上是对浏览器的一种 "哄骗", 让它认为自己访问到的是同域的 api. 实际上是在服务端做了个调包, 这个道理就如同你拨打 10086 你就认定了给你分配到的一定是中国移动的客服MM(客服GG也是有可能出现的 )而中国移动的客服MM就是一个很安全的聊天对象, 没有必要再进行限制...文章源自联网快讯-https://x1995.cn/4565.html
评论