当前位置: 首页 > 编程笔记 >

详解常用的nginx rewrite重写规则

鲜于致远
2023-03-14
本文向大家介绍详解常用的nginx rewrite重写规则,包括了详解常用的nginx rewrite重写规则的使用技巧和注意事项,需要的朋友参考一下

本文提供一些常用的rewrite重写规则,用来美化网页的链接。规则里面的$1$2你不知道是怎么来的话,只要记住,第一个()里面的是$1,第二个()里面的是$2.

请求的URL是给人看的,重写后的URL是给电脑看的。

执行搜索

这个规则的目的是为了执行搜索,搜索URL中包含的关键字。

请求的URL //hqidi.com/search/some-search-keywords
重写后URL //hqidi.com/search.php?p=some-search-keywords
重写规则         rewrite ^/search/(.*)$ /search.php?p=$1?;

用户个人资料页面

大多数运行访问者注册的动态网站都提供一个可以查看个人资料的页面,这个页面的URL包含用户的UID和用户名

请求的URL //hqidi.com/user/47/dige
重写后URL //hqidi.com/user.php?id=47&name=dige
重写规则         rewrite ^/user/([0-9]+)/(.+)$ /user.php?id=$1&name=$2?;

多个参数

有些网站对字符串参数使用不同的语法,例如 通过斜线“/”来分隔非命名参数

请求的URL //hqidi.com/index.php/param1/param2/param3
重写后URL //hqidi.com/index.php?p1=param1&p2=param2&p3=param3
重写规则         rewrite ^/index.php/(.*)/(.*)/(.*)$ /index.php?p1=$1&p2=$2&p3=$3?;

类似百科的格式

这种格式特点,一个前缀目录,后跟文章名称

请求的URL //hqidi.com/wiki/some-keywords
重写后URL //hqidi.com/wiki/index.php?title=some-keywords
重写规则         rewrite ^/wiki/(.*)$ /wiki/index.php?title=$1?;

论坛

论坛一般用到两个参数,一个话题标识(topic)一个出发点(starting post)

请求的URL //hqidi.com/topic-1234-50-some-keywords.html
重写后URL //hqidi.com/viewtopic.php?topic=1234&start=50
重写规则         rewrite ^/topic-([0-9]+)-([0-9]+)-(.*)\.html$ viewtopic.php?topic=$1&start=$2?;

新网站的文章

这种URL结构的特点,由一个文章标识符,后跟一个斜线,和一个关键字列表组成。

请求的URL //hqidi.com/88/future
重写后URL //hqidi.com/atricle.php?id=88
重写规则         rewrite ^/([0-9]+)/.*$ /aticle.php?id=$1?;

最后一个问号

若被替换的URI中含有参数(类似/app/test.php?id=5之类的URI),默认情况下参数会被自动附加到替换串上,可以通过在替换串的末尾加上?标记来解决这一问题。

rewrite ^/users/(.*)$ /show?user=$1? last;

比较一个加上?标记和不加?标记的URL跳转区别:

rewrite ^/test(.*)$ //hqidi.com/home premanent;

访问//hqidi.com/test?id=5 经过301跳转后的URL地址为 //hqidi.com/home?id=5

rewrite ^/test(.*)$ //hqidi.com/home? premanent;

访问//hqidi.com/test?id=5 经过301跳转后的URL地址为 //hqidi.com/home

Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记。

nginx rewrite指令执行顺序

1.执行server块的rewrite指令(这里的块指的是server关键字后{}包围的区域,其它xx块类似)
2.执行location匹配
3.执行选定的location中的rewrite指令

如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件。

如果循环超过10次,则返回500 Internal Server Error错误。

flag标志位

rewrite的语法很简单,如:

rewrite regex URL [flag];

rewrite是关键字,regex是正则表达式,URL是要替代的内容,[flag]是标记位的意思,它有以下几种值:

  • last: 相当于Apache的[L]标记,表示完成rewrite
  • break: 停止执行当前虚拟主机的后续rewrite指令集
  • redirect: 返回302临时重定向,地址栏会显示跳转后的地址
  • permanent: 返回301永久重定向,地址栏会显示跳转后的地址

因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解:

  • last一般写在server和if中,而break一般使用在location中
  • last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
  • break和last都能组织继续执行后面的rewrite指令

来看一个简单实例:

rewrite ^/listings/(.*)$ /listing.html?listing=$1 last;
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;

第一条重写规则中,我们可以使用友好的URL:http://mysite.com/listings/123代替http://mysite.com/listing.html?listing=123,就相当于我们在浏览器的地址栏中输入http://mysite.com/listings/123后,实际访问的URL资源是http://mysite.com/listing.html?listing=123。

第二条规则中,对形如http://mysite.com/images/bla_500x400.jpg的文件请求,重写到http://mysite.com/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。

if指令与全局变量

if指令语法为if(condition){...},对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行。

来看代码规则:

if ($http_user_agent ~ MSIE) {
  rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
 
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
  set $id $1;
 } //如果cookie匹配正则,设置变量$id等于正则引用部分
 
if ($request_method = POST) {
  return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
 
if ($slow) {
  limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
 
if (!-f $request_filename){
  break;
  proxy_pass http://127.0.0.1; 
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
 
if ($args ~ post=140){
  rewrite ^ http://mysite.com/ permanent;
} //如果query string中包含"post=140",永久重定向到mysite.com

if指令中,可以使用全局变量,这些变量有:

  • $args: #这个变量等于请求行中的参数,同$query_string
  • $content_length: 请求头中的Content-length字段。
  • $content_type: 请求头中的Content-Type字段。
  • $document_root: 当前请求在root指令中指定的值。
  • $host: 请求主机头字段,否则为服务器名称。
  • $http_user_agent: 客户端agent信息
  • $http_cookie: 客户端cookie信息
  • $limit_rate: 这个变量可以限制连接速率。
  • $request_method: 客户端请求的动作,通常为GET或POST。
  • $remote_addr: 客户端的IP地址。
  • $remote_port: 客户端的端口。
  • $remote_user: 已经经过Auth Basic Module验证的用户名。
  • $request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。
  • $scheme: HTTP协议(如http,https)。
  • $server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
  • $server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。
  • $server_name: 服务器名称。
  • $server_port: 请求到达服务器的端口号。
  • $request_uri: 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
  • $uri: 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
  • $document_uri: 与$uri相同。

使用return跳转

我们有时需要在Nginx上使用rewrite做301地址跳转,比如以下规则:

rewrite ^ $scheme://www.mysite.com$request_uri permanent;

当访问任意url都会301永久定向到www.mysite.com的url上。这个写法没错,但是因为使用了rewrite的正则匹配,会损耗一部分资源,nginx官网不推荐这样写。我们可以使用return同样可以实现301跳转,简单实用,看实例:

301永久定向到新域名

server {
  listen 80;
  listen 443 ssl;
  server_name www.old-name.com old-name.com;
  return 301 $scheme://www.new-name.com;
}

以上代码实现了老域名301跳转到新域名上,假如网站要更换新域名的话使用此方法做301跳转。

不带www的域名301跳转到带www的域名

server {
  listen 80;
  listen 443 ssl;
  server_name mysite.com;
  return 301 $scheme://www.mysite.com$request_uri;
}

http站点301跳转到https站点

server {
  listen 80;
  server_name www.mysite.com;
  return 301 https://www.mysite.com$request_uri;
}

以上就是有关Nginx的rewrite重写与重定向的介绍,觉得有用就请练习多遍,收藏好此文不迷路。也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍详解IIS中URL重写工具的规则条件(Rule conditions),包括了详解IIS中URL重写工具的规则条件(Rule conditions)的使用技巧和注意事项,需要的朋友参考一下 本文结合官方文档和相关示例,详细记录了在IIS中URL重写工具下的规则条件(Rule conditions)的相关说明。规则条件允许我们通过额外的逻辑规则来过滤和匹配规则模式( rule patt

  • dml2select Description:将数据库更新请求转换为只读查询请求,便于执行EXPLAIN Original: DELETE FROM film WHERE length > 100 Suggest: select * from film where length > 100 star2columns Description:为SELECT *补全表的列信息 Original:

  • 本文向大家介绍详解IIS中URL重写工具的匹配URL-规则模式(rule patterns),包括了详解IIS中URL重写工具的匹配URL-规则模式(rule patterns)的使用技巧和注意事项,需要的朋友参考一下 rule patterns规则模式在IIS的URL重写模块中,是较为关键的设置。只有规则模式的URL匹配成功时,其他的规则才能起到作用。规则模式的匹配URL设置主要是匹配URL中的

  • 本文向大家介绍Python中的作用域规则详解,包括了Python中的作用域规则详解的使用技巧和注意事项,需要的朋友参考一下 Python是静态作用域语言,尽管它自身是一个动态语言。也就是说,在Python中变量的作用域是由它在源代码中的位置决定的,这与C有些相似,但是Python与C在作用域方面的差异还是非常明显的。 接下来会谈论Python的作用域规则,在这中间也会说明一下Python与C在作用

  • 本文向大家介绍Python中异常重试的解决方案详解,包括了Python中异常重试的解决方案详解的使用技巧和注意事项,需要的朋友参考一下 前言 大家在做数据抓取的时候,经常遇到由于网络问题导致的程序保存,先前只是记录了错误内容,并对错误内容进行后期处理。 原先的流程: 改进后的流程: 最近发现的新的解决方案:retrying retrying是一个 Python的重试包,可以用来自动重试一些可能运行

  • 本文向大家介绍java中重写equals()方法的同时要重写hashcode()方法(详解),包括了java中重写equals()方法的同时要重写hashcode()方法(详解)的使用技巧和注意事项,需要的朋友参考一下 object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 tr