nginx 部署 vue 项目,给访问路径加前缀,配置同源策略

一、Nginx 的安装

官网下载并解压 nginx 压缩包。官网地址:nginx news

二、Nginx 常见命令

1.1、nginx 命令:
指定配置文件:nginx  -c filename  
验证配置(nginx.conf)是否正确: nginx -t

查看 Nginx 的版本号:nginx -V

启动 Nginx:start nginx

快速停止或关闭 Nginx:nginx -s stop

正常停止或关闭 Nginx:nginx -s quit

彻底杀死多个线程:taskkill /f /t /im nginx.exe

配置文件修改重装载命令 / 重启:nginx -s reload

1.2、其它常用命令:

端口号查看:netstat -ano|findstr :8090  
端口号服务:tasklist|findstr "12824"
打开文件: notepad hosts
hosts 修改后释放 命令行:ipconfig/release
重建本地 DNS 缓存 命令行:ipconfig /flushdns

 

三、Vue 中添加访问路径。比如 http://www.lpnm.com/CKManage

3.1、vue 的 vue.config.js 中进行配置

3.2、接着在对应的 router/index.js 中 添加路由配置

 3.3、yarn build 项目后,把打包后的文件,放在 nginx 路径下 html 文件夹下,新建一个文件夹 NeiMeng, 然后把包对应放进去

 

3.4、nginx 路径加前缀和不添加前缀配置

 
  1. server {
  2. listen 8071;
  3. server_name www.lpnm.com;
  4. # 设置跨域访问权限
  5. add_header Access-Control-Allow-Origin *;
  6. location / {
  7. root html\NeiMeng\BaseManage;
  8. index index.html index.htm;
  9. try_files $uri $uri/ @router; # 需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
  10. }
  11. location @router {
  12. rewrite ^.*$ /index.html last;
  13. }
  14. }
  15.  
  16. server {
  17. listen 8072;
  18. server_name www.lpnm.com;
  19. # 设置跨域访问权限
  20. add_header Access-Control-Allow-Origin *;
  21. location /CKManage {
  22. alias html\NeiMeng\CKManage;
  23. index index.html index.htm;
  24. try_files $uri $uri/ @router; # 需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
  25. }
  26. location @router {
  27. rewrite ^.*$ /CKManage/index.html last;
  28. }
  29. }
 

3.5、配置同源策略

两个不同端口的地址 www.lpnm.com:8071;www.lpnm.com:8072; 想通过 www.lpnm.com:8070 同时访问这两个地址

配置如下:

 
  1. #配置代理:
  2. server {
  3. listen 8070;
  4. server_name www.lpnm.com;
  5. location / {
  6. proxy_pass http://www.lpnm.com:8071/;
  7. }
  8. location /CKManage {
  9. proxy_pass http://www.lpnm.com:8072/CKManage;
  10. }
  11.  

一、前言

前后端分离后,如果想将前后端项目都放在同一台电脑上启动与开发,可以使用 nginx。

现将配置方法总结如下。

 

二、后端配置方法

1. 如果是 springboot 项目,要注意 application.yml 中的:

 
  1. server:
  2. port: 8080
  3. context-path: /survey
 
 

类似这样的配置,说明后端项目启动后,端口是 8080,前缀路径为 /survey。

 

2. 注意 pom.xml 中,如果有以下配置:

 
  1. <plugin>
  2. <groupId>org.apache.tomcat.maven</groupId>
  3. <artifactId>tomcat7-maven-plugin</artifactId>
  4. <configuration>
  5. <path>/survey</path>
  6. <port>8080</port>
  7. </configuration>
  8. </plugin>
 

这说明项目打好包启动后,端口是 8080,前缀路径为 /survey。

 

3. 查看 XXXController.java,注意以下部分:

(1) 类上的 RequestMapping 注解

 
  1. @Controller
  2. @RequestMapping("/survey-api")
  3. public class LoginController{}
 

这个说明,此 controller 中具体的路径前有一个前缀,为 /survey-api。

(2) 方法上的 RequestMapping/GetMapping/PostMapping 等注解

 
  1. @GetMapping("/login")
  2. public void login(HttpServletRequest req, HttpServletResponse resp){}
 

这个说明访问这个后台方法的路径的最后部分为 /login。

 

4. 因此,按照上方的例子,访问后台方法 login 的具体的 url 为:

http://localhost:8080/survey/survey-api/login

localhost 是本地 ip 的意思,如果后台项目启动在其它主机上,则访问时换成为其它主机的 ip。

 

三、前端配置方法

1. 前端可能会有一个总的配置文件,记录一个 ip,具体代码中只使用这个 ip 的引用。

就是声明一个全局变量,例如 IPCONFIG = 10.123.123.123:8081,之后用 IPCONFIG 拼接后缀形成 url。

这个全局变量可能用来拼接前端页面的 url,也有可能用来拼接后台接口的 url。

因此,打前端包时,应该修改这个参数为存放前端项目或后端项目的电脑的 IP + 端口。

 

2. 以本人接触的项目为例,vue 项目打好包后,生成 dist 文件夹,其中有一个 static 文件夹与 index.html 文件;

static 文件夹中,有一个 ipConfig.js;

ipConfig.js 中,配置了全局变量:

 
  1. const IPCONFIG="http://10.123.123.123:8081" //本地路径,开发用
  2. //const IPCONFIG="http://www.prodMyCompany.com" //生产路径,生产用
 

IPCONFIG 会被拼接为一些 url,进行参数传递与验签用。

10.123.123.123:8081 是本地电脑的 ip:nginx 监听的端口;

前端项目与后台项目都准备放在 10.123.123.123 上。(后台项目端口为 8080,下方 nginx 会配置)

 

 

四、nginx 配置方法

1. 为了使得配置文件不太混乱,使用新建配置文件并引入的方法。

 

2. 打开 D:/nginx-1.18.0/conf/nginx.conf 文件 (文件路径为参考样例),在末尾增加以下语句:

 
  1. include D://nginx-1.18.0//conf//upstream.conf;
  2. include D://nginx-1.18.0//conf.d//*.conf;
 

这两句的意思是,让 nginx.conf 配置文件包含 /conf/upstream.conf 文件,以及 conf.d 文件夹下的所有.conf 文件。

 

3. 在 conf 文件夹中创建 upstream.conf 文件,用来写 upstream 信息,例如:

 
  1. upstream project_survey {
  2. server localhost:8080;
  3. #server 10.123.123.123:8080;
  4. }
 

配置后,可以供后续使用;

准备把后端项目放到本地计算机上,用 8080 端口访问,用 project_survey 表示;

因此这么写。

 

4. 在 D:/nginx-1.18.0 / 文件夹中创建 conf.d 文件夹,在其中创建一个 my.conf 文件,用来写具体的 nginx 映射,例如:

 
  1. server {
  2. listen 8081;
  3. #listen 10.123.123.123:8081;
  4. server_name 10.123.123.123;
  5. #server_name www.hao1.com;
  6. #server_name www.hao2.com;
  7. #server_name localhost;
  8.  
  9.  
  10. location / {
  11. root D:\\project\\web;
  12. try_files $uri $uri/ /index.html;
  13. index index.html;
  14. }
  15.  
  16. location /survey-wrong/web {
  17. rewrite ^.+ http://localhost:8081/;
  18. #rewrite ^.+ http://localhost:8081/ break;
  19. }
  20.  
  21. location /project_survey {
  22. expires -1;
  23. proxy_set_header Host $http_host;
  24. proxy_read_timeout 1800;
  25. proxy_connect_timeout 1800;
  26. proxy_send_timeout 1800;
  27. proxy redirect off;
  28. proxy_set_header X-Real-IP $remote_addr;
  29. proxy_set_header REMOTE-HOST $remote_addr;
  30. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  31. client_max_body_size 2g;
  32.  
  33. proxy_pass http://project_survey;
  34. }
  35.  
  36. location ~ .*\.(gif|jpg|jpeg|png|css|js|ico)$ {
  37. root D:\\project\\web;
  38. proxy_temp_path D:\\project\\web;
  39. }
  40.  
  41. }
 

(1) listen 8081,说明 nginx 监听的是 8081 的请求。(如果配置了 ip,那么 server_name 就不生效了)

 

(2) server_name,配置域名。

当收到一个 url 请求,nginx 会先匹配 listen 中的 ip;如果没有配置 ip,再匹配 server_name;然后匹配 listen 中的端口。

上方例子配置的 server_name 是 10.123.123.123,listen 是 8081,因此收到 http://10.123.123.123:8081 的请求时,会走这个匹配规则,因为 server_name 与端口匹配成功了;

如果收到 http://localhost:8081 的请求时,也会走这个匹配规则,因为端口匹配成功了。

 

/*

如果本地 ip 不是 10.123.123.123,那么不会收到形如 http://10.123.123.123:8081 的请求,只会收到 http://localhost:8081 的请求,或者 http:// 本地 IP:8081 的请求,或者 http:// 本地域名:8081 的请求。

因此 server_name 可以配不配置都可以,只要 listen 配置了就可以了。

*/

参考:https://blog.csdn.net/qq_40737025/article/details/85053164

 

(3) location / 中配置的 D:\\project\\web,是前端项目所在的文件夹,其中 web 文件夹中有 index.html 文件以及 static 文件夹。这样使得请求 url 形如 / 的可以访问到本地的前端项目。

如访问 http://localhost:8081/,可以访问到 D:\\project\\web\\index.html。

root,将 url 中的头部分替换为指定部分,例如将 http://localhost:8081 替换为 D:\\project\\web。

try_files,先寻找 $uri,如果资源不存在,寻找 $uri/,如果资源还不存在,寻找 /index.html。

index,指定页面初始页,如果访问的 url 没有指定页面,则访问 index.html。

 

参考:https://www.cnblogs.com/boundless-sky/p/9459775.html

 

 

(4) location /survey-wrong/web,表示请求 url 中包含 /survey-wrong/web 时,全部重定向为 http://localhost:8081/,也就是重定向到首页。

其中,^.+ 是正则表达式,表示要匹配从第一个 (^) 开始、任意字符 (.)、有 1 - 多个 (+) 的内容;

匹配后,直接全部替换为指定地址。

因为 rewrite 进行了重定向,因此会从头开始重新匹配该 nginx 文件中配置的规则。(接着会走 location /,从而访问到 index.html)

 

/*

rewrite 后还可以加参数,例如 break 表示后续不再匹配其余规则等。

参考:https://www.cnblogs.com/brianzhu/p/8624703.html

*/

 

(5) location /project_survey,表示当请求 url 包含 /project_survey 时,会被替换为 proxy_pass 中的内容,http://project_survey;

而 project_survery 会被替换为 upstream 中的 localhost:8080,这个是后端项目的地址了。

 

例如访问

【http://localhost:8081/project_survery/survey/survey-api/login】

实际上访问的是

【http://localhost:8080/survey/survey-api/login】

 

nginx 会将匹配规则以及之前的部分全部替换为 proxy_pass 中的内容,后半部分保留;

对【location /project_survey】来说,

会将【http://localhost:8081/project_survery】替换为【http://localhost:8080】,然后拼接上剩余的【/survey/survey-api/login】

就得到了【http://localhost:8080/survey/survey-api/login】

这样就访问到后台接口了。

 

(6)location ~ .*\.(gif|jpg|jpeg|png|css|js|ico)$ ,

[.*] 表示任意字符、0 - 多个,

[\.] 表示字符.,

[$] 是字符串结尾位置,

也就是 url 请求中任意以.gif 或.jpg 或.jpeg 或.png 或.css 或.js 或.ico 结尾的,走这个匹配规则。

root 表示根路径要被替换为指定路径,

例如访问 http://localhost:8081/static/ipConfig.js

会将 http://localhost:8081 替换为

D:\\project\\web

实际访问了 D:\\project\\web/static/ipConfig.js

 

proxy_temp_path 为存储承载从代理服务器接收到的数据的临时文件定义目录。

 

参考:http://www.weixueyuan.net/a/662.html

 

 

5. 启动 nginx,启动后台项目,访问前端网页或后台接口,测试前后台能否成功通信。

例如访问前端 index.html,为【http://localhost:8081/】。

 

五、总结

1. 确定后端接口 url。(包含 ip、端口、controller 路径)

例如后端接口为:

http://127.1.2.3:8080/controller/login

 

2. 修改前端全局变量,改为本地的 ip+nginx 监听的端口。

例如:

const IPCONFIG = "http://127.1.2.3:8081"

 

3. 修改 nginx 配置文件,使得通过 url 可以访问到前端页面,并且前端页面可以发送请求给后台接口。

例如:

 
  1. server {
  2. listen 8081;
  3. server_name localhost;
  4.  
  5. location / {
  6. root D:\\project\\web;
  7. try_files $uri $uri/ /index.html;
  8. index index.html;
  9. }
  10.  
  11. location /controller {
  12. proxy_pass http://localhost:8080/controller;
  13. }
  14.  
  15. location ~ .*\.(gif|jpg|jpeg|png|css|js|ico)$ {
  16. root D:\\project\\web;
  17. proxy_temp_path D:\\project\\web;
  18. }
  19. }
 

 

(1) 访问 http://localhost:8081 / 或者 http://127.1.2.3:8081/,可以跳转到前端页面 D:\\project\\web\\index.html

(2) 前端页面发送请求给后台,规定 url 中要包含 /controller,这样就会被 nginx 转换为真实的后台 url,例如发送 [http://127.1.2.3:8081/controller/login],会把 [http://127.1.2.3:8081/controller] 替换为 [http://localhost:8080/controller],然后拼接剩余的 [/login],就访问到了 [http://127.1.2.3:8080/controller/login].

(3) 因为本地 ip 是 127.1.2.3,所以 localhost 等价于 127.1.2.3.

 

 

六、后记

1. 本文中的配置信息根据真实项目改编优化;如果有误,欢迎指出,作者会继续修改完善。

 

2. 关于 nginx 配置中,location 中末尾的【/】与 proxy_pass 中末尾的【/】的说明:

(1) 如果这么写:

 
  1. location /project_survey {
  2. proxy_pass http://127.1.2.3:8080;
  3. }
 

当访问 http://localhost:8080/project_survey/abc/abc 时,

由于存在【/project_survey】,匹配成功,nginx 会将【/project_survey】及之前的部分全部替换为 proxy_pass 中的内容,并保留之后的部分,

相当于访问了 http://127.1.2.3:8080/abc/abc。

(2) 如果这么写:

 
  1. location /project_survey/ {
  2. proxy_pass http://127.1.2.3:8080/;
  3. }
 

当访问 http://localhost:8080/project_survey/abc/abc 时,

由于存在【/project_survey/】,匹配成功,nginx 会将【/project_survey/】及之前的部分全部替换为 proxy_pass 中的内容,并保留之后的部分,

相当于访问了 http://127.1.2.3:8080/abc/abc。

(3) 如果这么写:

 
  1. location /project_survey {
  2. proxy_pass http://127.1.2.3:8080/;
  3. }
 

当访问 http://localhost:8080/project_survey/abc/abc 时,

由于存在【/project_survey】,匹配成功,nginx 会将【/project_survey】及之前的部分全部替换为 proxy_pass 中的内容,并保留之后的部分,

相当于访问了 http://127.1.2.3:8080//abc/abc,会多了一个【/】,倒是影响不太大。

(4) 如果这么写,就有问题了

 
  1. location /project_survey/ {
  2. proxy_pass http://127.1.2.3:8080;
  3. }
 

当访问 http://localhost:8080/project_survey/abc/abc 时,

由于存在【/project_survey/】,匹配成功,nginx 会将【/project_survey/】及之前的部分全部替换为 proxy_pass 中的内容,并保留之后的部分,

相当于访问了 http://127.1.2.3:8080abc/abc,少了一个【/】,此时路径就会出错。

(5) 所以概括为:要加都加,要不加都不加。

 

3.nginx 中 location 包含正则表达式的说明

(1) 包含正则表达式时,有时候会不按照最长匹配原则,而是按照匹配的先后顺序。如下:

 
  1. upstream survey{
  2. server 127.1.2.3:8080;
  3. }
  4.  
  5. location ~ /survey(.*) {
  6. set $name survey;
  7. proxy_pass http://$name/survey1$1$is_args$args;
  8. }
  9.  
  10. location ~ /survey/dev/search(.*) {
  11. set $name survey;
  12. proxy_pass http://$name/survey2/dev/search$1$is_args$args;
  13. }
 

当访问 http://localhost:8080/survey/dev/search/abc 时,

本来希望被转发到:

http://127.1.2.3:8080/survey2/dev/search/abc

实际被转发到:

http://127.1.2.3:8080/survey1/dev/search/abc

原请求同时符合这两个正则表达式,但是 nginx 走了上方的第一个匹配,而不是走最长匹配原则。

如果想实现需求,需要将上方的匹配规则换一下位置,才会走 survey2 那个:

 
  1. upstream survey{
  2. server 127.1.2.3:8080;
  3. }
  4.  
  5. location ~ /survey/dev/search(.*) {
  6. set $name survey;
  7. proxy_pass http://$name/survey2/dev/search$1$is_args$args;
  8. }
  9.  
  10. location ~ /survey(.*) {
  11. set $name survey;
  12. proxy_pass http://$name/survey1$1$is_args$args;
  13. }
 

(2) 上方代码参数解释:

~:区分大小写匹配

(.*):匹配 0 - 多个任意字符

$name:声明一个变量,值为 upstream 中的 survey,下方的 proxy_pass 使用时会被转为 ip。

$1:指 location 中的正则表达式匹配成功后的字符,即 (.*) 匹配得到的字符。

$is_args:请求中是否包含参数 (key-value),如果有,则继续拼接后面的字符;没有则为空。

$args:请求中的参数,没有则为空。

 

4.nginx 配置文件修改后没有生效的一种可能性

windows 下,启动 nginx.exe 或者用 cmd 启动 nginx 后,nginx 就会在后台运行;

之后关闭启动着 nginx 的 cmd 窗口、或者输入命令 nginx -s stop,有可能并不会完全关闭 nginx;

导致修改配置文件后、再次启动 nginx 时,配置文件没有生效 —— 是因为请求走到了使用旧配置文件的仍然存活的 nginx 上。(此时打开任务管理器可以发现多个 nginx 进程,之前的 + 新启动的)

解决方法是 cmd 输入:【taskkill /IM nginx.exe /F】,可以关闭所有启动了的 nginx;之后启动一个新的 nginx 即可。

 

posted @ 2024-07-01 10:08  CharyGao  阅读(190)  评论(0编辑  收藏  举报