一、项目基础路径相关配置导致转发404

经常我们可以碰到的转发无非是nginx转发到前端项目,nginx转发到后端项目两种情况。

1.1、后端项目

比如java项目为例,server.servlet.context-path定义了应用的上下文路径,它是构成url地址的一部分,一般在配置文件中定义。

  1. 不配置时,默认为/,如:localhost:8080/xxxxxx
  2. server.servlet.context-path有配置时,比如 /demo,此时的访问方式为localhost:8080/demo/xxxxxx

1.2、前端项目

例:vue.config.js文件

  1. const config = {
  2. publicPath: '',
  3. outputDir:'dist/api/doc/rmn/',
  4. productionSourceMap: false,
  5. };
  6. module.exports = config;

outputDir官网描述为设置项目打包生成的文件的存储目录,可以是静态路径也可以是相对路径。如果将outputDir设置为 dist/api/doc/rmn/ ,则执行完npm run build后,生成的包存放在dist/api/doc/rmn/ 下面。也就是说项目入口文件存放在rmn目录下。
image-20220106154540832.png


介绍了上面两种基础路径情况,下面来说,nginx转发到项目时,会造成404的情况。

通常我们使用类似下面的配置来转发到其他项目,这个时候不管基础路径是否配置,都可以转发到项目。

  1. location /api {
  2. proxy_set_header Upgrade $http_upgrade;
  3. proxy_set_header Connection "upgrade";
  4. proxy_pass http://sandbox.rop.pro;
  5. }

如果我们使用如下多级路径转发,那么就会造成404的情况,这个时候我们就需要将java项目的基础路径server.servlet.context-path配置为/api/rts,对于前端项目则需要修改outputDir:’dist/api/rts’,才能转发到目标项目。

  1. location /api/rts {
  2. proxy_set_header Upgrade $http_upgrade;
  3. proxy_set_header Connection "upgrade";
  4. proxy_pass http://sandbox.rop.pro;
  5. }

二、alias 和root使用不当引起404

  1. server {
  2. listen 80;
  3. server_name abc.huawei.com
  4. location /test {
  5. root /data/rts/;
  6. index aa.html aa.htm;
  7. }
  8. }

静态网站资源index.html,aa.html放置于/data/rts/目录下,当我们使用abc.huawei.com/test/访问项目的时候就会出现404的情况。

nginx的官方手册中例子

若用alias的话,则访问127.0.0.1/img/目录里面的文件时,ningx会自去/var/www/image/目录找文件

location /img/ { alias /var/www/image/; }

若用root的话,则访问/127.0.0.1/img/目录下的文件时,nginx会自动去/var/www/image/img/目录下找文件

location /img/ { root /var/www/image; }

因此为了正确访问项目,我们可以在/data/rts目录下创建test文件,并且将静态资源放置于test文件里。

三、转发过程中斜线“/”引起的404

在Nginx location通用匹配规则中配置proxy_pass转发时,假设有如下location配置:

  1. location /test {
  2. proxy_pass http://localhost:8080/test;
  3. proxy_redirect off;
  4. proxy_set_header X-Real-IP $remote_addr;
  5. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  6. proxy_set_header Host $host:$server_port;
  7. proxy_set_header X-Forwarded-Proto "https";
  8. proxy_set_header X-Forwarded-Host $host;
  9. proxy_set_header X-Forwarded-Server $host;
  10. proxy_set_header X-Real-IP $remote_addr;
  11. }

如果我请求 http://localhost/test/detect,则会将url根据匹配规则“/test”截取,然后将“/test”后面的内容(此处为“/detect”)拼接到proxy_pass的后面,然后转发,也就是最后实际请求地址为:proxy_pass http://localhost:8080/test/detect

所以,如果location的匹配规则最后不加斜线’/‘,则proxy_pass的最后也不要加斜线,或者都加上斜线,不然就不能正确访问实际地址,导致404 not found错误。

image.png