十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
Nginx 405 not allowed 异常要怎么办处理,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
成都创新互联是一家专注于成都网站制作、成都网站建设与策划设计,孟村网站建设哪家好?成都创新互联做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:孟村等地区。孟村做网站价格咨询:13518219792
今天遇到一个问题,当配置好的前端工程放到服务器上使用nginx启动的时候,报了405 Not allowed 异常,在网上百度了一下,说是这个问题出现的原因是因为使用了post 请求去获取静态资源,我觉得很奇怪,请求的接口都是业务接口,并不存在请求静态资源,是不是nginx对静态资源理解有什么误会,或者说我对静态资源理解不对,抱着这个想法,我把静态资源的概念又梳理了一遍:
静态资源:指的就是在html中的js/css/jpg/png/xxx.json...等等这些在前端工程中需要提前配置或者编译之后的文件,而且这些文件并不会时刻变化或者说变化周期比较长
好的,接下来我就试着根据百度出来的解决办法都尝试了一遍,毕竟网上这么多提出解决办法的,总有一个能解决吧,于是就开始尝试了各种网友的解决办法:
在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; } }
这样写是有问题的,有网友提到这样写只适用于post
请求中不带参数的请求,带参数的post
请求如果使用这种方式可能会导致参数体丢失
2. 修改nginx下src/http/modules/ngx_http_static_module.c文件,如下:
if (r->method & NGX_HTTP_POST) { return NGX_HTTP_NOT_ALLOWED; }
这个办法是修改nginx的源码,将这一段代码注释掉,重新编译,注意,注释的时候需要使用 /* */ 的方式,而不是 # 这个符号,不然会报错,参考这个
3. 修改错误界面指向(网上多流传这种方式,但是没有改变请求方法,所以行不通,所以采用以下方法),代码如下:
upstream static_backend { server localhost:80; } server { listen 80; error_page 405 =200 @405; location @405 { root /srv/http; proxy_method GET; proxy_pass http://static_backend; } }
这个处理的思路是将405的错误信息重新指向一个命名为@405
的location
地址,同时修改请求方式为get方法,这个方法同上面的第一个方法是一样的。这个location
将请求重新发送给proxy_pass
中定义的static_backend
,upstream
原本是用来配置负载均衡地址的,这里直接给了一个后台访问地址,思路没问题
不过,很不幸的是,上面这些方法中我试过了第一个和第三个,对我没有效果,第二个我就不去试了,我觉得nginx这样的设置肯定是有他的道理的,即使通过修改源码暂时达到了预期的效果,那这样也会带来隐患,难道以后就不升级nginx了吗,是吧,所以我觉得修改源码是最不靠谱的办法。
既然这几个方法都没有效果,那就看看后台服务的日志有没有收到请求,结果发现后台服务启动之后根本就没有收到Nginx 的任何请求转发,也就是说所有的请求(包括get
)都没有到达后台,此时我就开始怀疑是location
配置的问题,为什么这么说呢,因为如果是普通的405 not allowed
异常情况,至少get
请求是没有问题的,但是在查看控制台以及后台服务后发现,后台没有接收到请求,而浏览器的控制台中-network
一栏,get
请求的respone是一个静态页面,也并不是预想中的json数据,如下:
而在Headers
一栏显示请求是OK的,如下:
根据这个情况我更加确定,这个问题并不是它表现出来的 405 not allowed,很有可能是由于 location
配置异常导致了 405 not allowed,顺着这个思路我又复习了location
的配置,我原来的location 配置如下:
location = /demo { # rewrite ^.+demo/?(.*)$ /$1 break; proxy_pass http://localhost:19998; proxy_set_header Host $host:$proxy_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location / { root /home/jenkins/workspace/demo-2.0/dist; try_files $uri $uri/ /index.html; proxy_redirect http:// https://; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
这是一个严格匹配模式,在location
中有3中匹配模式,参考这个,分别是:
location = patt {} [精准匹配]
location patt{} [普通匹配]
location ~ patt{} [正则匹配]
其中精准匹配的优先级最高 --> 普通匹配 --> 正则匹配。
我将location = /demo {}
修改成了location /demo {}
就解决了问题,为什么呢?
个人理解,精准匹配是需要指定到具体某一个访问资源的,比如:location = /demo/index.html,应该这样写才对,我的post
请求中请求的url地址是一个很长串的地址,比如:localhost:19999/demo/user/query
这种,所以其实根本就没有匹配到 /demo
,而是匹配到了最下面的 location / {}
这里,所以请求全都被发送到了主页面上,导致nginx判断所有的请求都是在请求一个index.html,这违反了nginx的设计原则,即:不允许静态文件响应POST请求,所以才出现了***404 not allowed*** 的异常。
看完上述内容,你们掌握Nginx 405 not allowed 异常要怎么办处理的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!