Nginx如何实现pathinfo模式的方法详解

什么是pathinfo模式呢?

pathinfo是伪静态的一种,我们先解释一下伪静态的概念,伪静态页面是静态URL与动态URL互通的一个桥梁,它是指动态网址通过URL重写的手段去掉其动态参数,使URL静态化,但在实际的网页目录中并没有重写URL。简单来说,伪静态URL就是通过服务器转换伪装文件名或地址,使该页面类似于静态页面,但服务器上没有独立存在的文件,其本质还是动态页面。

使用过 ThinkPHP 框架开发应用的同学应该都会知道,它有一种 URL 模式就是 pathinfo,看起来类似下面的 URL:

http://example.com/module/controller/action/key1/value1/key2/value2.html

其实上面的 URL 的原型是下面的样子:

// 这个才是正宗的 URL,上面那个是冒牌的
http://example.com/index.php?m=module&c=controller&a=action&key1=value1&key2=value2

既然 pathinfo 模式的 URL 不是正宗的,那为什么不用正宗的呢,用正宗的不好吗?相对于正宗的 URL,pathinfo 模式的确实是有优势的,以下简单列举几项它的好处。

  • 它提供了最好的SEO支持
  • 可以实现 URL 的伪静态
  • 它看起来更简洁、更好看

pathinfo 模式的 URL 有这么多优点,那我们肯定要支持了。ThinkPHP 更多的 URL 模式配置及实现,可以参考这篇文档。

本文主要讨论的是 pathinfo 模式的 URL 在 Nginx 中的实现,ThinkPHP 官方文档中没有介绍,但是它实现起来也挺简单的。以下是实现过程的一些思考。

一个标准的通用的 URL 格式是类似下面那样子的:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

参照通用的 URL 格式,对比可以发现,pathinfo 模式的相对于标准模式的 URL,有两个地方的区别比较大,一个是没有了 index.php 文件,另一个是查询参数并没有使用符号“?”隔开。

现在要做的就是在 Nginx 接收的 pathinfo 模式的 URL 请求时,将它还原成标准的 URL 模式,这样服务器就能正常处理了。

把缺失的 index.php 文件补上

这个需要用到 Nginx 的 rewrite 指令,它的作用是将请求的 URI 替换成目标 URL。在这里需要达到的效果是,将

http://example.com/module/controller/action/key1/value1/key2/value2.html

替换成

http://example.com/index.php/module/controller/action/key1/value1/key2/value2.html

当然,并不是所有的 URI 都会进行此规则的重写,只有那些不是文件的 URI 才进行重写。所以,关于重写的指令将会类似下面的:

# 如果请求的文件不存在,则进行 URI 重写
# 在原有的基础上添加入口文件 index.php
if (!-e $request_filename) {
 rewrite ^/(.*)$ /index.php/$1 last;
}

通过以上配置就能达到补全 index.php 入口文件的效果了。

区分符号 ?前后的内容

在通用的 URL 中,符号“?”是具有特殊作用的,它是用来将查询字符串和前面的文件隔开。在 pathinfo 模式的 URL 中,符号“?”没有了,也就是说,服务器无法区分 URI 中哪些是文件,哪些是查询字符串了。所以,我们的目的是将 pathinfo 模式中本来应该由符号“?”区分的内容给手动区分开来。

还好,Nginx 中有个指令可以实现我们的目的,fastcgi_split_path_info。它可以将正则表达式定义的两个串分别赋值给变量 $fastcgi_script_name 和变量 $fastcgi_path_info,以供后文使用。更多关于 fastcgi_split_path_info 的信息,请查阅这里

相关配置类似下面的代码:

location ~ ^(.+\.php)(.*)$ {
 root /var/www/html/$vhost_path;
 fastcgi_pass phpfpm:9000;
 fastcgi_split_path_info ^(.+\.php)(.*)$;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_param PATH_INFO $fastcgi_path_info;

 include fastcgi_params;
}

一个简单的例子

通过上面两部份的配置,现在的 Nginx 服务器已经支持 pathinfo 模式的 URL 了,以下是一个简单的 server 配置,仅供参考:

server {
 listen 80;
 server_name tp5.loc;

 set $vhost_path tp5/public;

 location / {
 root /usr/share/nginx/html/$vhost_path;
 index index.php index.html index.htm;

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

 location ~ ^(.+\.php)(.*)$ {
 root /var/www/html/$vhost_path;
 fastcgi_pass phpfpm:9000;
 fastcgi_split_path_info ^(.+\.php)(.*)$;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_param PATH_INFO $fastcgi_path_info;

 include fastcgi_params;
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • CentOS6.3添加nginx系统服务的实例详解

    CentOS6.3添加nginx系统服务的实例详解 前言: 今天虚拟机上配了下服务器整理了个这个 nginx 服务 要注意 - 短横杠这个符号看看复制进去后有没有乱码,我之前就遇到这个问题,郁闷了好久才发现 提示:顶部的注释不要去除否则无法注册为系统服务, 关于:chkconfig: 2345 65 37 网上搜索总结了下意思是: 2345 为启动该服务的系统环境 65   为加载的优先级别 37   为关闭的优先级别 65,37 这两个位置的数值不能相同,也不能和其它服务的数值冲突,这个我也没

  • Nginx一个IP如何配置多个站点的方法教程

    前言 对于Nginx,一个IP上配置多个站点还是很常见的.尤其是在开发环境上,更是如此. 下面在我的阿里云上简单的实现这样一个需求: 在一个IP上通过对端口区分来配置多个站点. 环境初始化目录一览配置站点准备添加配置文件疑难杂项fastcgi_passNginxphp-fpm的进程间通信有两种方式总结 环境 手头上正好有一台阿里云学生机,趁着没过期,就拿来用吧. 操作系统:centOS7 php-fpm Nginx 初始化 在centos上搭建php-fpm+nginx环境不是很难,网上有很多的

  • Nginx 防止被域名恶意解析的办法

    Nginx 防止被域名恶意解析的办法 前言: 今天太倒霉了,发现通过IP无法访问服务器的80端口很无语,昨天都还好的啊,也没有修改过配置,其他端口又是正常的,防火墙也没问题.于是问了下机房,给了个崩溃的回复说我们的服务器有个域名没有备案被电信多次通告,然后就把我们ip端口给封了....封了啊...疯了,关键是这个域名TMD不是我的啊 经过一番折腾,发现是 nginx 配置上貌似有个漏洞,导致任何域名解析到服务器都能被正常请求,虽然是个空白页,但HTTP状态码是200. 主要是缺少下面的配置代码:

  • Laravel 5.5官方推荐的Nginx配置学习教程

    前言 本文主要给大家介绍了关于Laravel 5.5官方推荐的Nginx配置的想内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍把. Laravel 5.5 版本官方放出了 Nginx 服务器的配置,中文文档:服务器配置 Nginx server { listen 80; server_name example.com; root /example.com/public; add_header X-Frame-Options "SAMEORIGIN"; add_head

  • Nginx多层代理配置方法

    此篇只说nginx的多级代理配置,不扯其他的. 需求:hba.changyoufun.com-121.201.125.239(gd1)--hk1--co(alphaclash.ggdev.co)  广东代理--->香港--->加拿大 由于idc机房在加拿大,所以经常会配些nginx多级反向代理到国内.(不做代理client就得翻墙,或者说是丢包很严重.) 下面的Nginx配置我只写80的,443的忽略,简化nginx的配置,参数也不一一列举不然太多了. gd1的反向代理配置:(就是一个反向代理

  • 详解nginx 代理多个服务器(多个server方式)

    上一篇文章介绍了nginx的基本配置和使用方法,并且简单的介绍了一下如何利用nginx结合tomcat进行使用,达到反向代理的作用.现在我们要使用nginx达到这样的一个目的,能够代理多个服务器. 首先修改配置文件: #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/ngin

  • ThinkPHP 在阿里云上的nginx.config配置实例详解

    具体代码如下所示: # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log;

  • nginx使用nginx-rtmp-module模块实现直播间功能

    系统环境 wujianjun@wujianjun-work ~ $ uname -a Linux wujianjun-work 4.10.0-37-generic #41~16.04.1-Ubuntu SMP Fri Oct 6 22:42:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 软件环境 OBS(Open Broadcaster Software) v20.0.1 (Linux) nginx version: nginx/1.13.6 built

  • PHP使用Nginx实现反向代理

    一.代理服务器 1.什么是代理服务器 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬盘中,再发送给客户机. 2.为什么要使用代理服务器 1)提高访问速度 由于目标主机返回的数据会存放在代理服务器的硬盘中,因此下一次客户再访问相同的站点数据时,会直接从代理服务器的硬盘中读取,起到了缓存的作用,尤其对于热门站点能明显提高请求速度. 2)防火墙作用 由于所有的客户机请求都必须通过代

  • Nginx泛解析到子目录后自动判断有无public目录详解

    前言 我们大家在配置本地 PHP 开发环境时,除非是在 Windows 下,否则我都是偏向于 Nginx + PHP-FPM, 即使 Mac 下已经有了自带的 Apache+PHP 环境,依然如此.一方面是因为 Mac 自带的 PHP 版本不够新(5.6.x),另一方面,Nginx + PHP-FPM 更接近于我的生产服务器环境,而且也方便用 Homebrew 来管理版本和扩展. 在 Mac 下开发 Laravel, 官方提供了 valet, 可以方便地把子目录映射为虚拟主机,但我在使用的时候,

随机推荐