接口排查——nginx导致的404

4,362 阅读3分钟

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战


今天与前端进行接口联调时,调用接口提示404;通过nginx修改配置文件解决了这个问题,alis匹配的做的是字符串拼接,而不是路径的拼接。

一、问题排查与处理

前端到后端的路径:

  • 访问端口1001
  • nginx判断路径:
    • 如果路径包含/file/,会重写url指向本地的文件;
    • 对于其他的路径会转发到服务端的接口1000上。

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。

这个接口是通过其他接口改造过来的,除了路径其它的基本一致,且可以通过postman访问。本来以为是前端的ip写错了或改了之后没重启vue,因为这发生过。经过另一个前端同事排查后,发现局域网访问时确实会404,所以问题应该是nginx的配置有问题。

原先的配置如下所示,会把包含路径file的重写为根目录为resource的路径。

location ^~ /file {
    alias /resource/;
}

当请求http://10.1.0.21/1001/file/a.png 时,经过nginx转换为访问D:/resource/a.png(nginx位于D盘)。

修改成以下配置解决这个问题:

location ^~ /file/ {
    alias /resource/;
}

可以看到仅仅只是/file修改成/file/。其中,^~用于模糊匹配路径,alias表示进行路径重写。

使用^~进行匹配时,url并不会被视为一个路径,而是一个字符串;所以,/file不等同于/file/

二、nginx相关

常用命令

  • 查看版本号 nginx -V
  • 启动 start nginx
  • 重新加载配置文件 nginx -reload
  • 关闭 nginx -s quit
  • 快速停止 nignx -s stop

linux等待请求结束后关闭:

ps -ef |grep nginx
kill -QUIT  nginx主进程号

符号

容量符号缩写

k,K千字节
m,M兆字节

例如, "8k", "1m" 代表字节数计量.

时间符号缩写

ms毫秒
s
m分钟
h小时
d
w
M一个月, 30天
y年, 365 天

例如, "1h 30m", "1y 6M". 代表 "1小时 30分", "1年零6个月".

正则表达式

符号含义
=精确匹配
^~以某字符串开头
~区分大小写的正则匹配
~*不区分大小写的正则匹配
!~和!~*区分大小写的不匹配及正则
!~和!~*不区分大小写的不匹配正则
/用户代理

常用指令

1.root

root指令在 location 指令域时,root 设置的是 location 匹配访问路径的上一层目录。

例如:

location /t1/ { 
    root /a/b/c 
}

访问 http://localhost:1001/t1/d.png时,会查询/a/b/c/t1/d.png

2.alias

alias指令表示别名,用于重新定义指定的路径;会重写匹配字符串前的路径

例如:

location ^~ /file/ {
    alias /resource/;
}

访问 http://localhost:1001/file/d.png时,会查询{nginx-path}/resource/d.png

注:root可以没有斜杆;alias没有斜杠可能会导致错误

3.rewrite

rewrite用于重写url或重定向,可以使用全局变量或自定义变量。

相关语法:

rewrite regex replacement [flag]
  • regex表示正则表达式;
  • replacement表示用于替代的字符串;
  • flag表示重写的模式:
    • last 本条规则匹配完成后,继续向下匹配新的location URI规则
    • break 本条规则匹配完成即终止,不再匹配后面的任何规则
    • redirect 返回302临时重定向,浏览器地址栏会显示跳转后的URL地址
    • permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

生效作用域

  • server{}
  • location{}
  • if{}

rewrite重写时只能修改匹配字符串后面的url

4.proxy_pass

用于反向代理,一般用于映射ip以及端口。

例如

    location ~^/(test){
        proxy_pass http://127.0.0.1:8080/;
        client_max_body_size   10240k;
        client_body_buffer_size   128k;
    }
  • 访问 http://localhost:1001/t2/test/t1时,会访问http://127.0.0.1:8080/t1
  • 如果是 proxy_pass http://127.0.0.1:8080;,即后面没有斜杠,则访问http://127.0.0.1:8080/t2/test/t1.

三、参考

nginx
Location配置与ReWrite语法