一、nginx if判断无效
在使用nginx if语句时,有时候会发现if语句并没有按照预期执行,因此,在编写nginx规则时,请注意以下几点,以保证if语句可以正常运行:
1、if语句只能在 server、location、if 和 limit_except 块内使用。
2、if 后的条件必须用空格隔开。
3、if 后的条件不仅支持在 location 里设置,同时也支持在 server 块里设置。
4、在 location 里的 if 后如需使用反向代理,就不能用 try_files 。
如下所示,是一个if语句条件判断无效的例子:
server { listen 80; server_name example.com; if ($host = 'www.example.com') { return 301 $scheme://example.com$request_uri; } ... }
上述代码中,$host变量应该是通过nginx自动获取的,而它没有用空格隔开if语句的条件,因此if语句无效。正确的写法应该是:
server { listen 80; server_name example.com; if ($host = 'www.example.com') { return 301 $scheme://example.com$request_uri; } ... }
二、nginx iframe跨域
在前后端分离的项目中,为了保证安全性,通常会使用同源策略去限制页面的操作,例如防止跨域访问,但是有时候我们还是需要跨域访问,这时就需要用到 iframe 了。
当 iframe 的src属性的域名与父页面的域名不一致时,会出现跨域问题,此时,我们就可以利用nginx来解决这个问题。下面是一个利用nginx解决iframe跨域问题的示例:
location = /cross-domain.html { add_header 'Access-Control-Allow-Origin' 'http://target-site.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Credentials' 'true'; alias /path/to/cross-domain.html; }
上述代码中,另一个网站(target-site.com)想要在自己的网站上嵌入一个content-site.com的内容,此时需要访问包含在 cross-domain.html 文件中的 iframe,并且这个iframe要在target-site.com网站中访问,而访问时需要添加 Access-Control-Allow-Headers 和 Access-Control-Allow-Origin 等头信息,来实现某些getCredientials等操作。
三、nginx if判断
nginx if语句不仅可以判断变量,还可以根据自定义表达式进行判断,下面是其语法:
if(表达式1) {...} // 表达式 可以使用正则表达式来匹配字符串 if(表达式2) {...} // 表达式2 可以使用变量名,判断变量的值 if(表达式3) {...} // 表达式3 可以使用数字,判断变量是否等于/小于/大于指定数字
可以用来进行 if 判断的变量主要有:
1、$request_uri:请求uri
2、$host:请求的主机名
3、$http_x_forwarded_for:使用了proxy_pass代理后,客户端的Ip地址会被添加到http请求头的X-Forwarded-For字段中,使用$http_x_forwarded_for 来获取这个字段的值。
下面是一个使用if语句进行判断的示例:
location /path1 { if ( $host != 'www.example.com' ) { return 404; } proxy_pass http://backend2; }
上述代码中,只有当请求的主机名为www.example.com时,才会反向代理到http://backend2 去。
四、小结
通过以上的文章内容可以看到,nginx if语句的使用与运用有很多优点,如可以进行简单的判断操作,以及可以解决一些跨域问题。但需要注意if语句只能在server、location、if 和 limit_except 块内使用,并且if语句后的条件必须要用空格隔开。
代码示例:
server { listen 80; server_name example.com; if ($host = 'www.example.com') { return 301 $scheme://example.com$request_uri; } location = /cross-domain.html { add_header 'Access-Control-Allow-Origin' 'http://target-site.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Credentials' 'true'; alias /path/to/cross-domain.html; } location /path1 { if ( $host != 'www.example.com' ) { return 404; } proxy_pass http://backend2; } }