前后端分离后nginx与项目路径配置方法总结

一、前言

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

现将配置方法总结如下。

 

二、后端配置方法

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

server: 
  port: 8080
  context-path: /survey

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

 

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

<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <configuration>
    <path>/survey</path>
    <port>8080</port>
  </configuration>
</plugin>

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

 

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

(1)类上的RequestMapping注解

@Controller
@RequestMapping("/survey-api")
public class LoginController{}

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

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

@GetMapping("/login")
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中,配置了全局变量:

const IPCONFIG="http://10.123.123.123:8081" //本地路径,开发用
//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文件(文件路径为参考样例),在末尾增加以下语句:

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

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

 

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

upstream project_survey {
  server localhost:8080;
  #server 10.123.123.123:8080;
}

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

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

因此这么写。

 

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

server {
  listen 8081;
  #listen 10.123.123.123:8081;
  server_name 10.123.123.123;
  #server_name www.hao1.com;
  #server_name www.hao2.com;
  #server_name localhost;
  
  
  location / {
    root D:\\project\\web;
    try_files $uri $uri/ /index.html;
    index index.html;
  }

  location /survey-wrong/web {
    rewrite ^.+ http://localhost:8081/;
    #rewrite ^.+ http://localhost:8081/ break;
  }
  
  location /project_survey {
    expires -1;
    proxy_set_header Host $http_host;
    proxy_read_timeout 1800;
    proxy_connect_timeout 1800;
    proxy_send_timeout 1800;
    proxy redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 2g;

    proxy_pass http://project_survey;
  }

  location ~ .*\.(gif|jpg|jpeg|png|css|js|ico)$ {
    root D:\\project\\web;
    proxy_temp_path D:\\project\\web;
  }

}

(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可以访问到前端页面,并且前端页面可以发送请求给后台接口。

例如:

server {
  listen 8081;
  server_name localhost;

  location / {
    root D:\\project\\web;
    try_files $uri $uri/ /index.html;
    index index.html;
  }

  location /controller {
    proxy_pass http://localhost:8080/controller;
  }

  location ~ .*\.(gif|jpg|jpeg|png|css|js|ico)$ {
    root D:\\project\\web;
    proxy_temp_path D:\\project\\web;
  }
}

 

(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)如果这么写:

location /project_survey {
    proxy_pass http://127.1.2.3:8080;
  }

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

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

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

(2)如果这么写:

location /project_survey/ {
    proxy_pass http://127.1.2.3:8080/;
  }

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

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

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

(3)如果这么写:

location /project_survey {
    proxy_pass http://127.1.2.3:8080/;
  }

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

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

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

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

location /project_survey/ {
    proxy_pass http://127.1.2.3:8080;
  }

当访问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)包含正则表达式时,有时候会不按照最长匹配原则,而是按照匹配的先后顺序。如下:

upstream survey{
  server 127.1.2.3:8080;
}

location ~ /survey(.*) {
  set $name survey;
  proxy_pass http://$name/survey1$1$is_args$args;
}

location ~ /survey/dev/search(.*) {
  set $name survey;
  proxy_pass http://$name/survey2/dev/search$1$is_args$args;
}

当访问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那个:

upstream survey{
  server 127.1.2.3:8080;
}

location ~ /survey/dev/search(.*) {
  set $name survey;
  proxy_pass http://$name/survey2/dev/search$1$is_args$args;
}

location ~ /survey(.*) {
  set $name survey;
  proxy_pass http://$name/survey1$1$is_args$args;
}

(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即可。

 

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
前后端分离是指前端负责用户界面的展示和交互,后端负责业务逻辑的处理和数据的存储。在前后端分离的情况下,进行文件下载时,前端需要向后端请求文件资源并获取response才能进行下载。 然而,在某些情况下,可能会出现前后端分离文件下载没有response的问题。以下是可能导致该问题的一些原因和解决方法: 1. 后端未正确设置文件下载的response头信息:后端需要设置正确的Content-Disposition和Content-Type等响应头信息,以便告诉浏览器返回的是一个文件供下载。 解决方法:在后端代码中添加正确的响应头信息,例如在Java中可以使用HttpServletResponse的setHeader()方法进行设置。 2. 前端未正确处理后端返回的文件流:前端需要正确处理后端返回的文件流数据,以便将其保存为可供下载的文件。 解决方法:在前端代码中使用合适的方式处理后端返回的文件流,例如使用FileSaver.js库将文件保存到本地。 3. 前端请求未正确发送到后端:可能是由于前端发送请求的URL错误或者后端接口路径配置错误等原因导致请求未能正确发送到后端。 解决方法:确保前后端接口路径一致,并检查前端代码中发送请求的URL是否正确。 综上所述,前后端分离文件下载没有response的问题可能是由于后端响应头未设置、前端处理文件流不正确或者请求未正确发送到后端等原因所致。我们需要在前端和后端分别进行检查和调试,找出问题所在并采取相应的解决方法
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值