nginx系列(七)之各种小问题
nginx遇到的各种小问题就记录在这里吧,就不用老开新文章了。
一、nginx error_page遇到后端错误(如500)时不跳转
出现问题的情况:
服务器是用nginx+php做的web服务器,然后用nginx里面配置参数:try_files $uri $uri/ /index.php$is_args$args;做的入口隐藏设置。
如我现在的域名是:www.51niux.com啊,然后我访问网站的任何页面都显示的是www.51niux.com后面跟目录的形式,而非www.51niux.com/index.php?sd=das&cd=dsa这种形式。
下一次就是一些错误的HTTP状态码返回到指定的错误页面了,如404错误跳转到www.51niux.com/error,这个php动态程序做的error界面。
现象就出现了,如访问:www.51niux.com/2.php,这个在php文件不存在,然后我再nginx日志里面也看到了404,但是在server标签里面去捕捉404错误,竟然捕捉不到。
竟然要做下面的设置才能生效(我竟然要跑到php的location里面去捕捉这个文件存不存在,不存在就跳转到我指定的错误url:www.51niux.com/error):
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; if (!-e $request_filename) { rewrite /(.*)$ /error permanent; } }
php的404报错解决的,但是其他的错误如500,依旧捕捉不到啊,因为做了最上面的入口php文件隐藏设置之后,你再输入url,例如:www.51niux.com/dasda/dadas,nginx里面就不是404错误了,而是500错误。
下面是我nginx的配置:
error_page 400 404 500 = @not_found; location @not_found { rewrite /(.*)$ /error permanent ; }
#我让我指定的错误去发生跳转,跳转到我指定的url。但是却没有生效,因为我再server标签里面捕捉不到内部错误。
博文来自:www.51niux.com
我先做了下面的一种尝试(但是没有成功):
语法:proxy_intercept_errors on | off;
默认值:
proxy_intercept_errors off;
上下文:http, server, location
当被代理的后端服务器的响应状态码大于等于300时,决定是否直接将响应发送给客户端,亦或将响应转发给nginx由error_page指令来处理。
然后做了下面的尝试(可以了):
语法:fastcgi_intercept_errors on | off;
默认值:
fastcgi_intercept_errors off;
上下文:http, server, location
当FastCGI后端服务器响应状态码大于等于300时,决定是否直接将响应发送给后端客户端,或者将响应转发给nginx由 error_page指令来处理。
所以我最终的配置文件为:
#proxy_intercept_errors on; fastcgi_intercept_errors on; error_page 400 404 500 = @not_found; location @not_found { rewrite /(.*)$ /error permanent ; }
特此记录一下,如果没有适当的处理方法,nginx不会拦截一个错误
二、配置nginx支持 html5 video(ogv, webm.etc)播放
出现的问题:
网站上面设置的一些视频有的浏览器能播放,有的一打开带有视频的站点就会弹出迅雷的下载框,有的直接视频位置就是一个大的播放器图片,鼠标移动过去提示你不支持此种格式。
原因:
nginx默认丢失了 html5视频的媒体类型,比如Ogg\Ogv\WebM等,要支持这些媒体类型,必须自己添加相应媒体类型到 nginx/conf/mime.types文件中。不然浏览器不知道你的流媒体文件是什么类型,你得告诉浏览器,不然有的浏览器可能就会当成下载了,如果本地有迅雷并且默认是迅雷作为下载服务器,就会调用迅雷下载。
解决办法:
#cat /usr/local/nginx/conf/mime.types #添加下面的行,如果以前有老的ogg对应的行,删除掉,将上面七行加到mime.types 文件中。
application/ogg ogx; audio/ogg oga ogg spx; video/ogg ogv; video/webm webm; audio/webm weba; video/mp4 mp4; audio/mpeg m4a;
#重启nginx服务器,就能支持 html5 视频了。
三、root和alias的区别
root大家都比较理解,root为指定的目录,那么alias也是执行的目录,区别就是看下面的例子
location /img/ { alias /usr/local/nginx/html/image/; } #若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/usr/local/nginx/html/image/目录下找文件 location /img { root /usr/local/nginx/html/image; } #若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/usr/local/nginx/html/image/img/目录下找文件。
#这里要纠错一下,你看网上说的如果alias /usr/local/nginx/html/image/ 这个地方后面必须要加/,这句话是错的,这里来纠正一下。
location /img { alias /usr/local/nginx/html/image; #这里在结尾的地方是否加/,是跟上面设置的是对应的,如果上面没加,这里就不用加。 }
#这种设置还是比较正确的,这样不管你是访问192.168.1.103/img还是192.168.1.103/img/都会跳到/usr/local/nginx/html/image/这个目录下面去找对应的文件,如果尾部都加/,那么当你访问192.168.1.103/img这个的时候就会报403错误,之有加192.168.1.103/img/才可以。
四、nginx对站点目录设置密码加密
有的目录可能需要输入密码才能让直行,比如一些直行操作的脚本php文件等。
# yum install httpd-tools -y #需要htpasswd工具
# htpasswd -c -d /usr/local/nginx/conf/scripts_passwd admin #设置一个admin用户,然后会让你输入两次密码,用户密码文件会写到/usr/local/nginx/conf/scripts_passwd文件
location ^~ /scripts/ { #为什么要嵌套一个php的location呢?加上认证之后该目录下的php文件将不会被解析,会让你下载,如果要使其能够解析php可以将php的解析location放到认证授权的上面 location ~ .*\.(php|php5)?$ { #当然如果是单纯的目录加密就不需要加这个动态的location了 fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } auth_basic "Authorized users only"; #认证提示 auth_basic_user_file /usr/local/nginx/conf/scripts_passwd; #这就是认证文件 }
#chmod 600 /usr/local/nginx/conf/scripts_passwd
#chown www:root /usr/local/nginx/conf/scripts_passwd #注意给其文件授权为当前nginx运行用户,不然输完密码之后页面会报500错误。
五、访问不通的机器跳转到不通的目录
当然这并不是什么问题了,比如你有两台web服务器,国内一台,国外一台,当国外的访问这个域名的时候,DNS那里做了解析,就直接给你跳转到国外的哪台web机器了,国内的就是跳到国内的那台web机器上,如何实现国外的来源访问就跳转到/en目录下面,国内的访问就跳转到/cn目录下面呢?挺简单的,简单的配置下就可以了:
location / { index index.html; if ( $request_uri ~ ^/$ ) { #在首页下面做个判断,^/$单纯的是来判断是否就是访问的首页,如果是的话就做下面的rewrite rewrite ^(.*)$ /en/ permanent; #url就变成了www.51niux.com/en/的形式了。 } } location /en { #这里再有个location,上面请求就发送到这个目录 index index.html; alias /usr/local/nginx/html/ #注意这里,是alias的形式哦 }
#那么国内的那台机器,照着上面的样子改一改就可以了,将en改为cn就可以了。很简单就是简单记录一下。