背景:用户支付成功后的回调是个静态页面。由于from表单连续提交是post方式,所以会报405 not allowed 错误。
常识:使用post方式请求js、html这样的静态文件一般的web服务器都会返回405 Method Not Allowed。因为默认情况下,nginx、apache、IIs等web服务无法响应静态页面的post请求,后端用来处理post请求,生产环境中不会有此问题(一般都不允许配置静态页面的post请求)
问题:为什么默认不支持静态页面post请求呢?
首先了解一下post请求方法,post请求一般用于提交表单或上传文件,post请求会导致新资源的建立或旧资源的更改。就安全方面来说(排除url地址的透明性),它对比get请求会有更改资源的情况,有些静态资源是不允许更改的,所以默认情况下web服务器上的静态资源都不允许发起post请求。
网上说的有很多种,重新编译nginx,设置正则匹配可以访问html文件类啊什么的,都不好用,而且基本都是你抄我我抄你,没有实际应用过。乱糟糟,最后本人用下面这种方式解决了问题。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
upstream domain_uau { server 192.168.6.202:5555 weight=5; } server { listen 80; server_name dev-app-server.sinoif.com; access_log /var/www/logs/nginx/dev-app-server.sinoif-access.log; location / { proxy_set_header Host $host; 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_pass http://domain_uau/; add_header Cache-Control "no-cache, no-store";#不生成缓存 error_page 405 =200 @fullfuck; proxy_intercept_errors on; } location @fullfuck { proxy_method GET; proxy_pass http://192.168.6.202:5555; } } #error_page 405 =200 @fullfuck 或者 error_page 405 = @fullfuck; 2种写法都可以 #proxy_intercept_errors当上游服务器响应头回来后,可以根据响应状态码的值进行拦截错误处理,与error_page 指令相互结合。用在访问上游服务器出现错误的情况下,这个参数一定要带上并且开启on,否则下边不生效 |
1 2 3 |
@:定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请 求来访问,如try_files或error_page等 逻辑就是如果post请求返回了405错误,那么定义405区段请求为GET方式,注意 error_page 要写在location里,而不是server里否则不生效 |
其他nginx知识(随笔)
1 2 |
1.proxy_set_header Host $host :这一行的作用是把原http请求的Header中的Host字段也放到转发的请求里。如果不加这一行的话,nginx转发的请求header里就不会有Host字段,而服务器是靠这个Host值来区分你请求的是哪个域名的资源的。 3.proxy_set_header X-NginX-Proxy true :应该是代理转发的意思 true转发 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
2.proxy_set_header X-Real-IP $remote_addr 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这2个要放一起说: #$proxy_add_x_forwarded_for #$http_x_forwarded_for 这两个的变量的值的区别,就在于,proxy_add_x_forwarded_for 比 http_x_forwarded_for 多了一个$remote_addr的值 但是$remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面 但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip 那么这个时候就要用到X-FORward—for了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来,所以在获取用户真实ip的时候,一般就可以设置成,proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样就能获取所有的代理ip 客户ip 在打印log 的时候, #$http_x_real_ip|$remote_addr 就是用户的真实IP 配置如下 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 还有一种特殊情况就是 客户在经过cdn请求的时候,本来$proxy_add_x_forwarded_for这里记录的值都全部都包括,但是,当你需要取值的时候,会发现,即便用排除代理ip模块 set_real_ip_from 100.0.0.0/8;(这里是已知的代理ip) real_ip_header X-Forwarded-For; real_ip_recursive on; 也会导致 X-Forwarded-For 里依然有多个ip,这个时候直接取值$http_x_real_ip 就好了,但是前提条件是,cdn 那边也设置了X-forward,不然,你这边获取的你认为是用户的ip 其实是cdn的ip |
- 本文固定链接: https://www.yoyoask.com/?p=304
- 转载请注明: shooter 于 SHOOTER 发表