ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # 关于跨域 **前提** :**cookie** 是 **跨域不共享** 的,只有 **前端** 跟 **server 端 同一个域** 下,才不会产生跨域。 **问题** :例如 **前端** 启动的服务是 **localhost:8080** , **服务端** 启动一个服务,端口就不能是 **8080端口** ,因为同一台电脑会产生端口占用问题,所以它俩的 **端口不同,就产生了跨域** **解决** :通过 **nignx** 做代理,让前后端在同一个域下,就不会产生跨域了 **nginx** : **nginx** 可以做哪些事情? 1. 静态服务(静态图片等等) 2. 负载均衡(课里没有讲到) 3. 反向代理 **跨域有几种解决方案** : 1. jsonp 2. 配置cors 3. 前端使用脚手架配置代理 4. 配置nginx反向代理 >[success] ## 前端配置代理 拿 **vue** 举例,前端在 **开发阶段** 出现跨域问题时,通常使用代理的方式来解决跨域,步骤如下: 1. 在 **vue.config.js** 中配置要代理的地址,浏览器报错时未知请求都会匹配到这个地址上 2. 在 **axios** 中的 **baseURL** 中判断一下, **dev** 环境下使用空字符串 "" ,**prod** 环境下使用正式环境地址,也就是说我们 **在开发阶段时调用接口时,接口地址上没有域名,只有后面接口的名称** ,例如:**/api/base/login** ,到浏览器请求时,它才会自动匹配到 **代理地址 + /api/base/login** >[success] ## nginx配置反向代理 **1. 问题** :假如前端访问的页面地址是:**http://localhost:8001/index.html** 然后该页面调用的接口地址为 **http://localhost:8000/api/blog/list** ,它俩的 **端口不相同** 会产生 **跨域** 。 **2. 如何解决?** 1. 首先下载安装 **nginx** 2. 安装后配置 **nginx.conf** 文件,这里只需要改 **cpu核数** 、**端口号** 以及配置 2 个 **location** , **第1个配置是匹配静态页面 html ,第2个是匹配后端的接口地址** ~~~ nginx # 1核cpu worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 8080; # nginx端口号 server_name localhost; # 当前域名 # 匹配到/都指向下面这个配置静态页面路径 location / { proxy_pass http://localhost:8001; } # 匹配到有/api/都指向到这下方这个nodejs服务下 location /api/ { proxy_pass http://localhost:8000; proxy_set_header Host $host; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } ~~~ 修改完成后可以使用 `nginx -t` 指令来检查是否有语法错误,如果没有语法错误,执行 `nginx` 指令 **运行 nginx 服务** 3. 这里我们在浏览访问 nginx 的服务地址,http://172.18.2.198:8080/index.html ,结构如下: **nginx服务域名+端口号 + 本地静态文件地址 = http://172.18.2.198:8080/index.html** 为什么能在 **nginx服务** 上展示 **8001端口服务**的 **index.html** 页面呢?因为这个路径匹配到了 **nginx.conf** 的配置文件中的规则,如果通过nginx 服务地址(http://172.18.2.198:8080)打开的路径,都会被 **nginx.conf** 中的规则解析到,这个地址后面是 **/index.html** , 它被 **location** 中第一个规则 **/** 匹配到了,所以它被代理到了**http://localhost:8001/index.html** 这个地址,并且正常展示了 **index.html** 页面,流程图如下: ![](https://img.kancloud.cn/b2/12/b2124d16fd7cfb8d8c294e446167c0cf_742x401.png) 4. 我们在 **html 页面中调用接口时** ,也需要像 **vue项目** 中配置代理后调用接口一样,**baseURL** 需要为空,**接口的前缀也不允许有接口的域名地址**,代码如下: ~~~ var baseURL = "" // dev环境:空字符串,prod环境:线上地址 var apiPath = "/api/blog/list" var apiURL = `${baseURL}${apiPath}` // "/api/blog/list" // html页面中请求接口示例 $.get(apiURL).then(res => { console.log(res) }) ~~~ 这样我们在请求接口时候,他会自动匹配成 **nginx的域名全路径**:**http://172.18.2.198:8080/api/blog/list** ,就跟我们在 **vue** 中做的代理一样,baseURL为空时,他会自动去 **匹配代理**,此时它就会走到 **nginx.conf** 的配置文件中的 **location** 中第 **2** 个规则 **/api/** ,然后它就会被代理到 **http://localhost:8000/api/blog/list** 这个地址下,这样就完美的解决了跨域。 >[success] ## 总结 所谓的 **nginx反向代理** ,实际上就是把 **多个不同的访问地址(路径)** ,在 **nginx** 的服务的 **域名端口** 上进行访问,**这样它们就都使用同一个域名端口号** 了,也就不会产生跨域问题了,然后 **nginx** 在自己的内部自己来根据配置的规则,来区分这些调用的地址应该代理到哪里,就好像一个中间层一样,用户访问浏览器时候访问的实际上是 nginx 的中间层,nginx来做处理来告诉浏览器你应该匹配到哪些地址。 更官方一些的说法就是: **Nginx反向代理** 可以 **将多个不同的访问地址映射到同一个域名端口上** ,从而 **避免了跨域问题** 。同时, **Nginx作为中间层** , **可以根据用户请求中的某些信息(例如URL路径、Host头等)** 来 **判断应该将请求转发到哪个后端服务器** ,实现请求的动态路由。这样可以提高系统的灵活性和可扩展性,同时也能够有效地保护应用服务器的安全