1

背景

前端时间上线项目的时候,由于第一次上线没有经验。报了几个错误。

405 Not allowed

当时的nginx.conf配置


server {
    listen       80 default_server;
    listen  [::]:80 default_server;

    access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://gitlabwebhooktogithub-api:8088/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
405 报错

服务器上使用 nginx 启动的时候 并访问如下时,报了 405 Not allowed 异常

http://gitlab-webhook-to-github.xxxxxx:17081

去谷歌了一下,说是这个问题出现的原因是因为使用了 post 请求去获取静态资源,

我觉得很奇怪,明明是用post请求后台接口,为什么变成请求静态资源,是因为项目打包后变成静态了吗?

感觉可能对静态资源理解不对,抱着这个想法,我把静态资源的概念又梳理了一遍:

静态资源:指的就是在 js/css/jpg/png/xxx.json... 等等这些在前端工程中需要提前配置或者编译之后的文件,而且这些文件并不会时刻变化或者说变化周期比较长。
同时 Apache、IIS、Nginx等绝大多数web服务器,都不允许静态文件响应POST请求。
尝试解决

同时,那篇文章下面还给了解决方式:

在 location 中配置 error_page,这个解决问题的思路是将 post 请求转换成 get 请求,配置信息如下:

server {
    listen       80;
    server_name  域名;
   location /{
       root /www/文件目录;
       index index.html index.htm index.php;
       error_page 405 =200 http://$host$request_uri;
    }
 }

但是没有效果,报错依旧。

查看后台是否收到请求

既然方法没有效果,那就看看后台服务的日志有没有收到请求。

于是在application.yml 添加了 日志功能,将日志打印到本目录到 my.log 文件中

server:
  port: 8088

logging:
  file: my.log

在后台的接口上打印信息,若收到请求,则打印。
logger.info("接收到请求");

查看日志: 后台没有收到请求
image.png

也就是说所有的请求(包括 get)都没有到达后台

于是我又去查看了 url 以及 nginx配置

location /api/ {
    proxy_pass http://gitlabwebhooktogithub-api:8088/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


需要加上 api 后缀,才能转发给后台。真是粗心大意

301 Moved Permanently

加上 api 后缀后, url为

http://gitlab-webhook-to-github.xxxxxx:17081/api 

之后又发生了新的报错: 301 Moved Permanently

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr>
<center>nginx/1.23.1</center>
</body>
</html>

为啥服务端会返回301呢?

首先需要弄清楚状态码的含义, HTTP协议中3xx开头的状态响应码都是表示重定向的响应。根据RFC的定义:

  • 301 Moved Permanently
  • 302 Found
  • 303 See Other
  • 307 Temporary Redirect

301是永久重定向。如果使用Nginx作为HTTP服务器,那么当用户输入一个不存在的地址之后,基本上会有两种情况:

  1. 返回404状态码,
  2. 返回301状态码和重定向地址。只说下301 Moved Permanently的处理过程。

下面这种情况 Nginx 会主动设置3 01 Moved Permanently 状态码:

当用户在浏览器输入了一个url地址,末尾部分是一个文件目录且不以斜杠”/“结尾,比如 “www.baidu.com/index” 。
Nginx没有找到index这个文件,但发现了index是个目录。于是本次访问的返回状态码就会被设置成301 Moved Permanently。

流程图:
image.png

原因就是: url对应的位置为目录

再去后台找发现: @RequestMapping("")

猜想是不是需要加 / 才能正常访问此controller

@RestController
@RequestMapping("")
@Slf4j
public class GitLabController {

    @Autowired
    private NotifySchedule notifySchedule;

    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity pushHook(@RequestBody String json,
                               @RequestHeader(name = "X-Gitlab-Event") String event,
                               @RequestHeader(name = "X-Gitlab-Token", required = false) String secret) {
        if (secret == null) {
            ResponseVo body = ResponseUtil.error(HttpStatus.UNAUTHORIZED,"未在系统中添加secret, 请求失败");
            return  new ResponseEntity<>(body, HttpStatus.UNAUTHORIZED);
        }
       return notifySchedule.putIntoMap(json, event, secret);
    }
}

之后又在 api 下 加了个斜杠 /

http://gitlab-webhook-to-github.xxxxxx:17081/api/

果然访问成功。

image.png


为什么重定向自动加的斜杠不生效

回过头一想, 重定向的时候不是自动加上了 斜杠/ ,为什么也没有成功?

image.png

再去重定向的地址一看:没有自动加上 端口号,导致重定向失败

总结:

第一个错误,url不对导致没有转发给后台
第二个错误,url不对导致没有访问到正确的controller


weiweiyi
1k 声望123 粉丝