nginx的url重写怎么用

发布时间 - 2023-05-19 00:00:00    点击率:

nginx之url重写

1.url重写模块(rewrite)

摘要这个模块允许使用正则表达式重写uri(需pcre库),并且可以根据相关变量重定向和选择不同的配置。如果这个指令在server字段中指定,那么将在被请求的location确定之前执行,如果在指令执行后所选择的location中有其他的重写规则,那么它们也被执行。如果在location中执行这个指令产生了新的uri,那么location又一次确定了新的uri。这样的循环可以最多执行10次,超过以后nginx将返回500错误。

break

语法:break 

默认值:none 

使用字段:server, location, if 

完成当前设置的规则,停止执行其他的重写指令。 

示例:

if ($slow) {
 limit_rate 10k;
 break;
}

if

语法:if (condition) { … } 

默认值:none 

使用字段:server, location 

注意:在使用if指令之前请查看if is evil page并且尽量考虑用try_files代替。 

判断一个条件,如果条件成立,则后面的大括号内的语句将执行,相关配置从上级继承。 

  • 可以在判断语句中指定下列值:

  • 一个变量的名称;不成立的值为:空字符传”“或者一些用“0”开始的字符串。

  • 一个使用=或者!=运算符的比较语句。

  • 使用符号~*和~模式匹配的正则表达式:

  • ~为区分大小写的匹配。

  • ~*不区分大小写的匹配(firefox匹配firefox)。

  • !~和!~*意为“不匹配的”。

  • 使用-f和!-f检查一个文件是否存在。

  • 使用-d和!-d检查一个目录是否存在。

  • 使用-e和!-e检查一个文件,目录或者软链接是否存在。

  • 使用-x和!-x检查一个文件是否为可执行文件。

正则表达式的一部分可以用圆括号,方便之后按照顺序用$1-$9来引用。 

示例配置:

if ($http_user_agent ~ msie) {
 rewrite ^(.*)$ /msie/$1 break;
}
                                                                            
if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
 set $id $1;
}
                                                                            
if ($request_method = post ) {
 return 405;
}
                                                                            
if (!-f $request_filename) {
 break;
 proxy_pass http://127.0.0.1;
}
                                                                            
if ($slow) {
 limit_rate 10k;
}
                                                                            
if ($invalid_referer) {
 return  403;
}
                                                                            
if ($args ~ post=140){
 rewrite ^ http://example.com/ permanent;
}

内置变量$invalid_referer用指令valid_referers指定。

return

语法:return code 

默认值:none 

使用字段:server, location, if 

这个指令结束执行配置语句并为客户端返回状态代码,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416与500-504。此外,非标准代码444将关闭连接并且不发送任何的头部。

rewrite

语法:rewrite regex replacement flag 

默认值:none 

使用字段:server, location, if 

按照相关的正则表达式与字符串修改uri,指令按照在配置文件中出现的顺序执行。 

可以在重写指令后面添加标记。 

如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。 

尾部的标记(flag)可以是以下的值:

  • last - 完成重写指令,之后搜索相应的uri或location。

  • break - 完成重写指令。

  • redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。

  • permanent - 返回301永久重定向。

注意如果一个重定向是相对的(没有主机名部分),nginx将在重定向的过程中使用匹配server_name指令的“host”头或者server_name指令指定的第一个名称,如果头不匹配或不存在,如果没有设置server_name,将使用本地主机名,如果你总是想让nginx使用“host”头,可以在server_name使用“*”通配符(查看http核心模块中的server_name)。例如:

rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
return  403;

但是如果我们将其放入一个名为/download/的location中,则需要将last标记改为break,否则nginx将执行10次循环并返回500错误。

location /download/ {
 rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
 rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  break;
 return  403;
}

如果替换字段中包含参数,那么其余的请求参数将附加到后面,为了防止附加,可以在最后一个字符后面跟一个问号:

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

注意:大括号({和}),可以同时用在正则表达式和配置块中,为了防止冲突,正则表达式使用大括号需要用双引号(或者单引号)。例如要重写以下的url:

/photos/123456

为:

/path/to/photos/12/1234/123456.png

则使用以下正则表达式(注意引号):

rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

如果指定一个“?”在重写的结尾,nginx将丢弃请求中的参数,即变量$args,当使用$request_uri或$uri&$args时可以在rewrite结尾使用“?”以避免nginx处理两次参数串。 

在rewrite中使用$request_uri将www.example.com重写到example.com:

server {
  server_name www.example.com;
  rewrite ^ http://example.com$request_uri? permanent;
}

同样,重写只对路径进行操作,而不是参数,如果要重写一个带参数的url,可以使用以下代替:

if ($args ^~ post=100){
 rewrite ^ http://example.com/new-address.html? permanent;
}

注意$args变量不会被编译,与location过程中的uri不同(参考http核心模块中的location)。

rewrite_log

语法:rewrite_log on | off 

默认值:rewrite_log off 

使用字段:server, location, if 

变量:无 

启用时将在error log中记录notice 标记的重写日志。

set

语法:set variable value 

默认值:none 

使用字段:server, location, if 

指令设置一个变量并为其赋值,其值可以是文本,变量和它们的组合。 

你可以使用set定义一个新的变量,但是不能使用set设置$http_xxx头部变量的值。

uninitialized_variable_warn

语法:uninitialized_variable_warn on|off 

默认值:uninitialized_variable_warn on 

使用字段:http, server, location, if 

开启或关闭在未初始化变量中记录警告日志。 

事实上,rewrite指令在配置文件加载时已经编译到内部代码中,在解释器产生请求时使用。 

这个解释器是一个简单的堆栈虚拟机,如下列指令:

location /download/ {
 if ($forbidden) {
  return  403;
 }
 if ($slow) {
  limit_rate 10k;
 }
 rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

将被编译成以下顺序:

variable $forbidden
checking to zero
recovery 403
completion of entire code
variable $slow
checking to zero
checkings of regular excodession
copying "/"
copying $1
copying "/mp3/"
copying $2
copying ".mp3"
completion of regular excodession
completion of entire sequence

注意并没有关于limit_rate的代码,因为它没有提及ngx_http_rewrite_module模块,“if”块可以类似”location”指令在配置文件的相同部分同时存在。 

如果$slow为真,对应的if块将生效,在这个配置中limit_rate的值为10k。 

指令:

rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;

如果我们将第一个斜杠括入圆括号,则可以减少执行顺序:

rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;

之后的顺序类似如下:

checking regular excodession
copying $1
copying "/mp3/"
copying $2
copying ".mp3"
completion of regular excodession
completion of entire code

2.简单案例

注,由于配置文件内容较多,为了让大家看着方便,我们备份一下配置文件,打开一个新的配置文件。

[root@nginx ~]# cd /etc/nginx/
[root@nginx nginx]# mv nginx.conf nginx.conf.proxy
[root@nginx nginx]# cp nginx.conf.bak nginx.conf
[root@nginx nginx]# vim /etc/nginx/nginx.conf
server {
   listen    80;
   server_name localhost;
   #charset koi8-r;
   #access_log logs/host.access.log main;
   location / {
     root  html;
     index index.html index.htm;
     rewrite ^/bbs/(.*)$ http://192.168.18.201/forum/$1;
   }
}

准备forum目录与测试文件

[root@web1 ~]# cd /var/www/html/
[root@web1 html]# ls
index.html
[root@web1 html]# mkdir forum
[root@web1 html]# cd forum/
[root@web1 forum]# vim index.html

forum page!

测试一下

好了,下面我们来测试一下rewrite重写。

3.重新加载一下配置文件

[root@nginx 63]# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新载入 nginx:                      [确定]

4.测试一下

注,大家可以从图中看出,status code 302指的是临时重定向,那就说明我们rewrite重写配置成功。大家知道302是临时重定向而301是永久重定向,那么怎么实现永久重定向呢。一般服务器与服务器之间是临时重定向,服务器内部是永久重定向。下面我们来演示一下永久重定向。

5.配置永久重定向

[root@nginx nginx]# vim /etc/nginx/nginx.conf
server {
    listen    80;
    server_name localhost;
    #charset koi8-r;
    #access_log logs/host.access.log main;
    location / {
      root  html;
      index index.html index.htm;
      rewrite ^/bbs/(.*)$ /forum/$1;
    }
}

准备forum目录与测试文件

[root@nginx ~]# cd /usr/html/
[root@nginx html]# ls
50x.html index.html
[root@nginx html]# mkdir forum
[root@nginx html]# cd forum/
[root@nginx forum]# vim index.html

192.168.18.208 forum page

6.重新加载一下配置文件

[root@nginx ~]# service nginx reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新载入 nginx:                      [确定]

7.测试一下

注,大家从图中可以看到,我们访问bbs/是直接帮我们跳转到forum/下,这种本机的跳转就是永久重定向也叫隐式重定向。


# nginx  # 重写  # 重定向  # 配置文件  # 默认值  # 正则表达式  # 测试一下  # 是否存在  # 第一个  # 将在  # 其他的 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何用好域名打造高点击率的自主建站?  Laravel怎么使用artisan命令缓存配置和视图  如何安全更换建站之星模板并保留数据?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  C++用Dijkstra(迪杰斯特拉)算法求最短路径  使用spring连接及操作mongodb3.0实例  制作公司内部网站有哪些,内网如何建网站?  如何快速上传自定义模板至建站之星?  Laravel定时任务怎么设置_Laravel Crontab调度器配置  如何批量查询域名的建站时间记录?  canvas 画布在主流浏览器中的尺寸限制详细介绍  javascript基本数据类型及类型检测常用方法小结  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  js实现获取鼠标当前的位置  活动邀请函制作网站有哪些,活动邀请函文案?  做企业网站制作流程,企业网站制作基本流程有哪些?  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程  零服务器AI建站解决方案:快速部署与云端平台低成本实践  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  制作电商网页,电商供应链怎么做?  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环  制作企业网站建设方案,怎样建设一个公司网站?  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  网站建设整体流程解析,建站其实很容易!  ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】  linux top下的 minerd 木马清除方法  详解jQuery中的事件  如何在新浪SAE免费搭建个人博客?  北京专业网站制作设计师招聘,北京白云观官方网站?  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】  LinuxShell函数封装方法_脚本复用设计思路【教程】  简单实现Android文件上传  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  如何在云服务器上快速搭建个人网站?  如何用5美元大硬盘VPS安全高效搭建个人网站?  js实现点击每个li节点,都弹出其文本值及修改  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Laravel怎么实现模型属性的自动加密  奇安信“盘古石”团队突破 iOS 26.1 提权  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  Laravel集合Collection怎么用_Laravel集合常用函数详解