Nginx + php-fpm 平台组合下,想实现 https://proxy.mimvp.com/doc/apidoc.php 隐藏 .php后缀的效果,即输入:https://proxy.mimvp.com/doc/apidoc

网上搜了一大堆,都多介绍隐藏 index.php重定向到入口文件,这不是我想要的。

还有人说 Nginx 不行,只能用 Apache,然而我只轻轻的改了改,一切就是那么的简单,正是我要的效果!

其实很简单,一行代码的事情​

location / {
     try_files $uri $uri/ $uri.php?$args;
}

或者

location / {
	try_files $uri $uri/ 	/index.php?$query_string;
}

含义说明:

当用户请求 http://localhost/xxx/example 时,这里的 $uri 就是 /xxx/example

try_files 会到根目录下尝试找 /xxx/example 这个文件。如果存在名为 /$root/xxx/example(其中 $root 是项目代码安装的根目录)的文件,就直接把这个文件的内容发送给用户。 

显然,目录中没有叫 /xxx/example 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 /$root/example/ 的目录(文件夹)。 

发现,又找不到 /xxx/example/ 目录(文件夹),就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php

 

现在下面两组url的访问效果是一样的

before:

https://proxy.mimvp.com/login.php

https://proxy.mimvp.com/register.php

https://proxy.mimvp.com/blog/post.php

https://proxy.mimvp.com/xxx/xxx/anything.php

after:

https://proxy.mimvp.com/login

https://proxy.mimvp.com/register

https://proxy.mimvp.com/blog/post

https://proxy.mimvp.com/xxx/xxx/anything

 

 

Nginx 配置选项 try_files 详解

Nginx的配置语法灵活,可控制度非常高,用户可高度自定义配置选项。

在0.7以后的版本中加入了一个try_files指令,配合命名location,可以部分替代原本常用的rewrite配置方式,提高解析效率。

try_files是nginx中http_core核心模块所带的指令,主要是能替代一些rewrite的指令,提高解析效率。

官网文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files

 

try_files的语法规则:

格式1:try_files file ... uri

格式2:try_files file ... =code;

可应用的上下文:server,location段

try_files的语法解释:(先贴出官方的解释,楼主再解释下)

Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the fileparameter according to the root and alias directives. It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made. 

关键点1:按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理

关键点2:查找路径是按照给定的root或alias为根路径来查找的

关键点3:如果给出的file都没有匹配到,则重新请求最后一个参数给定的uri,就是新的location匹配

关键点4:如果是格式2,如果最后一个参数是 = 404 ,若给出的file都没有匹配到,则最后返回404的响应码

举例说明:

location /images/ {
    root /opt/html/;
    try_files $uri   $uri/  /images/default.gif; 
}

解析步骤:请求 127.0.0.1/images/test.gif 会依次查找

1. 文件/opt/html/images/test.gif

2. 文件夹 /opt/html/images/test.gif/下的 index.html, index.htm, index.php 等 index文件

3.  请求127.0.0.1/images/default.gif

注意事项:

try-files 如果不写上 $uri/,当直接访问一个目录路径时,并不会去匹配目录下的索引页index, 即访问127.0.0.1/images/ 不会去访问 127.0.0.1/images/index.html

 

匹配自定义标记点

location / {
    try_files /system/home.html
              $uri $uri/index.html $uri.html
              @mimvp_home;
}

location @mimvp_home {
    proxy_pass http://mimvp.com;
}

以上中若未找到给定顺序的文件/system/home.html、$uri、$uri/index.html、$uri.html,则将会交给location @mimvp_home处理(相当于匹配到了@mimvp_home来匹配)

 

try_files 指令说明

语法:try_files file … uri try_files file … = code

作用域:serverlocation

其作用是按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数

需要注意的是,只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。

最后一个参数是回退URI且必须存在,否则会出现内部500错误。命名的location也可以使用在最后一个参数中。

与rewrite指令不同,try_files 如果回退URI不是命名的location那么$args不会自动保留,如果你想保留$args,则必须明确声明。

try_files $uri $uri/ /index.php?q=$uri&$args;

实例分析

1、try_files 将尝试你列出的文件并设置内部文件指向。

例如:

try_files /app/cache/ $uri @fallback;
index index.php index.html;

它将检测$document_root/app/cache/index.php,$document_root/app/cache/index.html 和 $document_root$uri是否存在,如果不存在着内部重定向到@fallback(@表示配置文件中预定义标记点) 。

你也可以使用一个文件或者状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在。

 

2、nginx不解析PHP文件,以文本代码返回

try_files $uri /cache.php @fallback;

因为这个指令设置内部文件指向到 $document_root/cache.php 并返回,但没有发生内部重定向,因而没有进行location段处理而返回文本 。

(如果加上index指令可以解析PHP是因为index会触发一个内部重定向)

 

 

3、跳转到预定义标记点变量

server {
	listen 8000;
	server_name proxy.mimvp.com;
	root html;
	index index.html index.php;

	location /abc {
		try_files /4.html /5.html @mimvp_home;  	# 检测文件4.html和5.html,如果存在正常显示,不存在就去查找@qwe值
	}

	location @mimvp_home {
		rewrite ^/(.*)$ http://www.mimvp.com; 		# 跳转到米扑科技首页
	}
}

 

4、跳转指定文件

server {
	listen 8000;
	server_name proxy.mimvp.com;
	root html;
	index index.php index.html;

	location /abc {
		try_files /4.html /5.html /6.html;		# 匹配/abcxxx, 依次跳转到指定的网页
	}
}

 

5、将请求跳转到后端服务器

upstream tornado {
	server 127.0.0.1:8001;
}

server {
	server_name mimvp.com;
	return 301 $scheme://proxy.mimvp.com$request_uri;
}	

server {
	listen 80;
	server_name proxy.mimvp.com;

	root /var/www/proxy.mimvp.com/V0.3/www;
	index index.html index.htm;

	try_files $uri @tornado;

	location @tornado {
		proxy_pass_header 	Server;
		proxy_set_header 	Host $http_host;
		proxy_set_header 	X-Real-IP $remote_addr;
		proxy_set_header 	X-Scheme $scheme;

		proxy_pass 			http://tornado;
	}
}

 

常见错误

1、try_files 按顺序检查文件是否存在,返回第一个找到的文件,至少需要两个参数,但最后一个是内部重定向也就是说和rewrite效果一致,前面的值是相对$document_root的文件路径。也就是说参数的意义不同,甚至可以用一个状态码 (404)作为最后一个参数。如果不注意会有死循环造成500错误。

location ~.*\.(gif|jpg|jpeg|png)$ {
	root /web/wwwroot;
	try_files /static/$uri $uri;
}

原意图是访问http://example.com/test.jpg时先去检查/web/wwwroot/static/test.jpg是否存在,不存在就取/web/wwwroot/test.jpg

但由于最后一个参数是一个内部重定向,所以并不会检查/web/wwwroot/test.jpg是否存在,只要第一个路径不存在就会重新向然后再进入这个location造成死循环。结果出现500 Internal Server Error

location ~.*\.(gif|jpg|jpeg|png)$ {
	root /web/wwwroot;
	try_files /static/$uri $uri 404;
}

这样才会先检查/web/wwwroot/static/test.jpg是否存在,不存在就匹配第二个取/web/wwwroot/test.jpg,若还不存在则匹配最后一项返回404 not found

 

 

2、Nginx try_files $query_string为空的解决办法

server {
	listen 80;
	server_name proxy.mimvp.com;
	index index.php index.html index.htm;
	set $root_path '/var/www/html/public';
	root $root_path;

	location / {
		try_files $uri $uri/ /index.php;
	}

	location ~ \.php$ {
		try_files 			$uri =404;
		fastcgi_split_path_info 	^(.+\.php)(/.+)$;
		fastcgi_pass 		127.0.0.1:9000;
		fastcgi_index 		index.php;
		fastcgi_param 		SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params;
	}

	location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
		root $root_path;
	}

	location ~ /\.ht {
		deny all;
	}
}

发现PHP无法获取$_GET信息

try_files $uri $uri/ /index.php;

改为

try_files $uri $uri/ /index.php?$query_string;

 

 

 

Nginx 隐藏 .php 后缀

location / {
     try_files $uri $uri/ $uri.php?$args;
}

 

Nginx 重定向

loaction / {
	try_files $uri @apache
}

loaction @apache{
	proxy_pass http://127.0.0.1:88
	include aproxy.conf
}

try_files方法让Ngxin尝试访问后面得$uri链接,若找不到 $uri ,则根据@apache配置进行内部重定向。

当然try_files也可以以错误代码赋值,如try_files /index.php = 404 @apache,则表示当尝试访问的文件(/index.php)返回404时,根据@apache配置项进行重定向。

 

 

Nginx 配置URL重写(实现隐藏index.php)

方式1:index 索引

location / {
    root        html;
    index       index.php index.html index.htm;
    include     fastcgi.conf;
}

 

方式2:正则表达式

location / {
	root html/xxxx/yyyy/;
	index index.php index.html;
	if (  !-e  $request_filename ){
		rewrite(.*) /index.php/$1;
	}
}

示例:/auth/login       index.php?/auth/login

说明:/auth/login  若找不到,则重定向到 index.php?/auth/login

 

方式3:try_files

location / {
    root html/dddai/public/;
    index index.php index.html;
    try_files $uri /index.php?$uri;
}

示例:/auth/login       index.php?/auth/login

说明:/auth/login  若找不到,则重定向到 index.php?/auth/login

try_files 的含义,实际包含了 if ( !-e $request_filename ) 判断

 

 

Apache 与 Nginx下实现伪静态,隐藏index.php文件

1、伪静态的概念

伪静态是地址栏看起来是静态,改变了地址的表现形式,但是后台处理的还是动态页面。

例如:米扑博客 https://blog.mimvp.com/article/37586.html  ----> https://blog.mimvp.com/?p=37586

说明:采用 WordPress 搭建,默认后台是 PHP动态页面,但显示出来的是 HTML 静态页面

 

2、伪静态的优缺点

优点:在SEO方面,伪静态和静态页面是一样的,由于搜索引擎比较喜欢收录静态页面,所以伪静态容易被搜索引擎收录;再一点就是为了安全,将一个网站的实现语言及路径隐藏起来,使网站的信息不暴露给外界。

缺点:由于伪静态是用正则实现的,正则表达式增加了服务器的负荷,使用了伪静态会使网站的承受能力降低。

 

3、伪静态的实现

1)Apache下实现

①将httpd.conf里的LoadModule rewrite_module modules/mod_rewrite.so 前边的#号去掉

②将搜索AllowOverride将所有的AllowOverride None修改为AllowOverride All

③将options里的FollowSymLinks打开,否则会报403 Forbidden错误

④建立一个.htaccess文件(可以新建一个txt文件,然后另存为.htaccess),将这个文件放在文件根目录里,里面的内容为以下

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

⑤重启Apache服务器

 

2)Nginx下实现:

打开配置nginx虚拟主机的配置文件 nginx.conf,在与server里和location同级的地方加上以下内容,重启nginx服务器

if (!-e $request_filename) {
    rewrite ^/(.*)  /index.php/$1 last;
}   

说明:以  / 开头(Web任何目录都是以 / 开头的)的零个或任意多个字符,默认使用 /index.php/$1  解析, 其中 $1 代表 (.*) 中的内容

 

Nginx配置无 .html 后缀

米扑科技刚做了官网,官网网页都是html文件,领导要求访问时隐藏.html后缀。

服务器用的是nginx,这样需求的解决方案是修改配置文件:

location / {
     //添加上以下代码:
     if (!-e $request_filename){
         rewrite ^(.*)$ /$1.html last;
         break;
     }
}

 

 

参考推荐

Nginx 配置 Location 指令块

Nginx location 正则匹配规则

Nginx rewrite 隐藏 .php 后缀

Nginx 配置文件详解

Nginx使用ssl模块配置HTTPS

Nginx Redirect重定向所有子域名到www

LNMP(CentOS+Nginx+Mysql+PHP)服务器环境配置

Apache 设置禁止访问网站目录

Apache Rewrite 规则 RewriteCond、RewriteRule 参数配置详解

Apache 封禁IP及IP段访问

httpd使用ssl模块配置HTTPS

实用 .htaccess 用法大全

.htaccess绑定域名到子目录

Linux grep 正则表达式