https://www.linuxidc.com/Linux/2012-07/66760.htm

Nginx的405错误解决办法

[日期:2012-07-30]来源:Linux社区  作者:cnsanshao[字体:大 中 小]
 
 
访问服务使器URL用IE浏览器可以下载,但是用客户端测试就没办法,提示网络错误,在客户端那边,得到的结果就是405错误,这个是nginx返回的。于是,在我的电脑上拿浏览器,输入制定的url,那客户端模拟器都可以打开,于是查看了日志,发现了其中的不同。浏览器是用发送的GET请求,而客户端是发送的POST请求。

日志如下:

xxx.xxx.xxx.xxx- – [xx/xxx/2xxx:14:00:00 +0800] “POST /xxxxxxx.xxxx HTTP/1.1″ “405″ 173 “-” “curl/7.12.1 (i686-RedHat-linux-gnu) libcurl/7.12.1 OpenSSL/0.9.7a zlib/1.2.1.2 libidn/0.5.6″ “-”

其中前面的xxx是请求源的ip,后面的POST 那的是访问的文件。

于是上网搜索,类似的问题,发现了其中的原因,下面是张宴老师的博客里对这个问题的处理方法,下面有

URL:http://www.linuxidc.com/Linux/2012-07/66761.htm

对于这种情况的解释是,由于访问静态文件的时候只能使用GET方式,不能使用POST,因此呢,在nginx的返回信息中,在0.6.33版以后就增加了这么一个405错误状态码,意思就是,你不能用POST方式来请求静态文件,错了,要换个别的方法。

具体的change log是在nginx的官方站点上看到的,内容如下:

URL:http://www.nginx.net/CHANGES-0.6

Changes with nginx 0.6.33 20 Nov 2008

*) Feature: now nginx returns the 405 status code for POST method
requesting a static file only if the file exists.

但是我们希望POST方式可以被支持,于是张老师的配置里面,就重定向了405返回为200,就是如果遇到405,就当成200处理。

具体配置,关键部分如下:

error_page 405 =200 @405;
location @405
{
root /opt/htdocs;
}

重定向了405->200了,并且给405这个错误指定了doc_root,就是正常的doc_root的配置。

于是,按照上面的配置以后,发现并没有生效,还是返回405,当时就钻牛角尖了,觉得是nginx的问题,于是换了低版本的0.6.35的版本,还是不行,随机上网搜到两种方法。

1,用post_to_static 这个patch,但是苦于我实在不知道怎么打这个patch,最后我崩溃了。。否则的话,重新编译一个nginx就支持post_to_static这个配置项,就可以选择on/off来开关,实现允许POST请求访问静态页面。

可以参考的url如下:
http://www.linuxidc.com/Linux/2012-07/66762.htm 这个写的和张老师一样,但是帮我解释了为什么前面要有rewrite的问题。

2,第二种,用proxy_pass来使用代理访问,但是我重定向到了127.0.0.1:port/以后,也没好使,还出现了502的错误。

url如下:http://www.linuxidc.com/Linux/2012-07/66763.htm 看上去不错,但是也没用,要配置proxy_pass必须在localtion里面,貌似。

3,第三种是一个很好的思考方向,但是没有能起作用,大概需要继续修改一下。

# location ~ (.xxx1$|.xxx2$) {
# root /home/xxxxx/htdocs;
# index index.html index.htm;

#if ($request_method != GET) {
# set $request_method GET;
#}
# fastcgi_param REQUEST_METHOD GET;
# }

这里就是想,如果访问和我们规则匹配的文件时候,如果访问的请求不是GET,那么我们就给$requset_method的变量赋值为GET,但是这里没有用到fcgi可能下面拿句就不能生效,并且如果同时出现两个$requset_method的话,配置文件检测的时候,会提示语法错误,变量重复,这里我觉得这里如果url请求过来了,这里的这个变量可能就无法改变了,再重新赋值也不能了,但是rul为什么能改写呢,这个是一个疑问。

以上的方法都没有解决问题,最后让瀚哥给乱试验出来了,,这里鄙视一下他。。没次都能这样乱试验出来,看来我们有时候得不要被规矩限制,或者是被现有手头的成功案例束缚。

具体配置如下:

location ^~ /xxxx.xxx1 {
root /home/xxxxxx/htdocs;
error_page 405 =200 /xxxx.xxx1;
}

location ^~ /xxxx.xxx2 {
root /home/xxxxxx2/htdocs;
error_page 405 =200 /xxxx.xxx2;
}

为什么error_page在内部生效而不是在server那个部分生效,,就不得而知了。

而且这里的配置不具有灵活性,不过也确实是因为有两个文件,单独配置,直接指定了去哪里下载,连重定向以后的root都直接成了文件。

================
本人的成功配置案例如下:
   location /
   {
     root  /www/client/domain;
      index index.shtml index.html;
      error_page 405 =200 /index.shtml;
   }

   location ~* /*\.shtml$
   {
      root  /www/client/$domain;
      index index.shtml index.html;
      error_page 405 =200 http://$domain$request_uri;
   }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐