背景:用户支付成功后的回调是个静态页面。由于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文件类啊什么的,都不好用,而且基本都是你抄我我抄你,没有实际应用过。乱糟糟,最后本人用下面这种方式解决了问题。
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
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
upstreamdomain_uau{
server192.168.6.202:5555weight=5;
}
server{
listen80;
server_namedev-app-server.sinoif.com;
access_log/var/www/logs/nginx/dev-app-server.sinoif-access.log;
location/{
proxy_set_headerHost$host;
proxy_set_headerX-Real-IP$remote_addr;
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
proxy_set_headerX-NginX-Proxytrue;
proxy_passhttp://domain_uau/;
add_headerCache-Control"no-cache, no-store";#不生成缓存
error_page405=200@fullfuck;
proxy_intercept_errorson;
}
location@fullfuck{
proxy_methodGET;
proxy_passhttp://192.168.6.202:5555;
}
}
#error_page 405 =200 @fullfuck 或者 error_page 405 = @fullfuck; 2种写法都可以
#proxy_intercept_errors当上游服务器响应头回来后,可以根据响应状态码的值进行拦截错误处理,与error_page 指令相互结合。用在访问上游服务器出现错误的情况下,这个参数一定要带上并且开启on,否则下边不生效
@:定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请
求来访问,如try_files或error_page等
逻辑就是如果post请求返回了405错误,那么定义405区段请求为GET方式,注意 error_page 要写在location里,而不是server里否则不生效
1
2
3
@:定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请
求来访问,如try_files或error_page等
逻辑就是如果post请求返回了405错误,那么定义405区段请求为GET方式,注意error_page要写在location里,而不是server里否则不生效
其他nginx知识(随笔)
1.proxy_set_header Host $host :这一行的作用是把原http请求的Header中的Host字段也放到转发的请求里。如果不加这一行的话,nginx转发的请求header里就不会有Host字段,而服务器是靠这个Host值来区分你请求的是哪个域名的资源的。
3.proxy_set_header X-NginX-Proxy true :应该是代理转发的意思 true转发
1
2
1.proxy_set_headerHost$host:这一行的作用是把原http请求的Header中的Host字段也放到转发的请求里。如果不加这一行的话,nginx转发的请求header里就不会有Host字段,而服务器是靠这个Host值来区分你请求的是哪个域名的资源的。
3.proxy_set_headerX-NginX-Proxytrue:应该是代理转发的意思true转发
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
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_headerX-Real-IP$remote_addr和
proxy_set_headerX-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_headerX-Forwarded-For$proxy_add_x_forwarded_for;这样就能获取所有的代理ip客户ip
在打印log的时候,
#$http_x_real_ip|$remote_addr
就是用户的真实IP
配置如下
proxy_set_headerX-Real-IP$remote_addr;
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;
还有一种特殊情况就是
客户在经过cdn请求的时候,本来$proxy_add_x_forwarded_for这里记录的值都全部都包括,但是,当你需要取值的时候,会发现,即便用排除代理ip模块
set_real_ip_from100.0.0.0/8;(这里是已知的代理ip)
real_ip_headerX-Forwarded-For;
real_ip_recursiveon;
也会导致
X-Forwarded-For
里依然有多个ip,这个时候直接取值$http_x_real_ip就好了,但是前提条件是,cdn那边也设置了X-forward,不然,你这边获取的你认为是用户的ip其实是cdn的ip
最后编辑:2019-11-20作者:shooter
这个作者貌似有点懒,什么都没有留下。