• WEB服务-Nginx之11-rewrite


    WEB服务-Nginx之11-rewrite

    Rewrite基本概述

    Rewrite主要实现url地址重写,以及重定向,也就是把传入web的请求重定向到其他url的过程。


    Rewrite使用场景

    1. 地址跳转,用户访问www.abc.com这个URL时,将其定向至一个新的域名www.def.com

    2. 协议跳转,用户通过http协议请求网站时,将其重新跳转至https协议

    3. 伪静态,将动态页面显示为静态页面方式的一种技术。

      • 便于搜索引擎的录入

        搜索引擎,SEO优化依赖于url路径,好记的url便于搜索引擎录入

      • 减少动态URL地址对外暴露的参数,提高安全性。


    ngx_http_rewrite_module模块用于使用PCRE正则表达式更改请求URI,返回重定向,并有条件地选择配置。

    Syntax:  rewrite regex replacement [flag]
    Default: -
    Context: server,location,if
    

    如果指定的正则表达式与请求URI匹配,则URI将按照replacement字符串中的指定进行更改。

    rewrite按其在配置文件中出现的顺序依次执行。可以使用标志终止指令的进一步处理。如果替换字符串以“ http://”,“ https://”或“ $scheme” 开头,则处理停止,并将重定向返回给客户端。

    示例:用于切换维护页面时

    rewrite ^(.*)$ /page/maintain.html break;
    

    Rewrite标记flag

    rewrite指令根据正则表达式来重定向URL,或者修改字符串,支持如下flag标记:

    flag 作用
    last 本条规则匹配完成后,停止匹配,不再匹配后面的规则
    break 本条规则匹配完成后,停止匹配,不再匹配后面的规则
    redirect 返回302临时重定向,地址栏会显示跳转后的地址
    permanent 返回301永久重定向,地址栏会显示跳转后的地址

    总结:301和302直接在用户访问的页面跳转,用户可以直观的看到跳转,而last和break是后端跳转,用户无法发现,301和302实际中用的比较多。


    last与break对比示例

    类似于循环中的breakcontinue

    [root@web01 ~]# cat > /etc/nginx/conf.d/rewrite.conf <<EOF
    server {
        listen 80;
        server_name www.rewrite.com;
        root /code;
    
        location ~ ^/break {
            rewrite ^/break /test/ break;
        }
        location ~ ^/last {
            rewrite ^/last /test/ last;
        }
        location /test/ {
            default_type application/json;
            return 200 "ok";
        }
    }
    EOF
    

    nginx配置文件语法检测,重载服务

    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    添加hosts解析

    [root@web01 ~]# echo 10.0.0.7 www.rewrite.com >> /etc/hosts
    

    访问测试

    [root@web01 ~]# curl www.rewrite.com/break
    <html>
    <head><title>404 Not Found</title></head>
    <body>
    <center><h1>404 Not Found</h1></center>
    <hr><center>nginx/1.18.0</center>
    </body>
    </html>
    [root@web01 ~]# curl www.rewrite.com/last
    ok
    

    创建所需目录再测试

    [root@web01 ~]# mkdir /code/test
    [root@web01 ~]# curl www.rewrite.com/break
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.18.0</center>
    </body>
    </html>
    

    last与break区别

    break:匹配成功后不再向下匹配,也不会跳转到其他的location,会去配置的本地目录中寻找请求的文件,给客户端返回结果数据;

    last:匹配成功后不再向下匹配当前location的后续rewrite规则,并结束当前location,然后用生成的新URL跳转至其所在的server{...}区块的其他location继续匹配,直到没有location可匹配后,将最后一次location的数据返回给客户端。

    break请求:
    1、请求www.rewrite.com/break
    2、首先:会去查找本地的/code/test/index.html;
    3、如果找到了,则返回/code/test/index.html的内容;
    4、如果没找到该目录报错404,如果找到该目录没找到对应的文件报错403

    last请求:
    1、请求www.rewrite.com/last
    2、首先:会去查找本地的/code/test/index.html;
    3、如果找到了,则返回/code/test/index.html的内容;
    4、如果没找到,会对当前server重新发起一次请求,www.rewrite.com/test
    5、如果有location匹配成功,则直接返回该location的内容。
    4、如果没有location匹配成功,最后返回404;

    所以,在访问/break和/last时,虽然对应的请求目录/test都是不存在的,理论上都应该返回404,但是实际上访问/last的时候,可以返回后面location所匹配到的结果。


    redirect与permanent对比示例

    [root@web01 ~]# vi /etc/nginx/conf.d/rewrite.conf
    server {
        listen 80;
        server_name www.rewrite.com;
        root /code;
    
        location /test {
            rewrite ^(.*)$  https://www.baidu.com redirect;
            #return 302 https://www.baidu.com;
            
            #rewrite ^(.*)$  https://www.baidu.com permanent;
            #return 301 https://www.baidu.com;
    
        }
    }
    

    nginx配置文件语法检测,重载服务

    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    添加hosts解析

    windows配置:在C:WindowsSystem32driversetchosts文件中添加一行10.0.0.7 www.rewrite.com

    redirect测试浏览器访问www.rewrite.com/test

    image-20200923141317918

    permanent测试浏览器访问www.rewrite.com/test

    image-20200923141506238

    注意:permanent跳转的地址保存在浏览器缓存中,测试时不要勾选Disable cache!!!

    image-20200923142018765


    redirect与permanent区别

    redirect: 每次请求都会询问服务器,如果当服务器不可用时,则会跳转失败。

    permanent: 第一次请求会询问,浏览器会缓存记录跳转的地址,之后则不再询问服务器,直接通过浏览器缓存的地址跳转。

    Rewrite开启日志

    在写rewrite规则之前,我们需要调整error_log级别,开启rewrite日志,对规则的匹配进行调试。

    [root@web01 ~]# sed -i '/^error_log.*/c error_log  /var/log/nginx/error.log notice;' /etc/nginx/nginx.conf
    [root@web01 ~]# sed -i '/http {/a rewrite_log on;' /etc/nginx/nginx.conf
    

    Rewrite规则实践

    案例一

    用户访问/abc/1.html实际上真实访问的是/ccc/bbb/2.html

    http://www.rewrite.com/abc/1.html ==> http://www.rewrite.com/ccc/bbb/2.html

    # 1.准备真实访问目录和文件
    [root@web01 ~]# mkdir /code/ccc/bbb -p
    [root@web01 ~]# echo "ccc_bbb_2" > /code/ccc/bbb/2.html
    
    # 2.nginx跳转配置
    [root@web01 ~]# cat > /etc/nginx/conf.d/rewrite.conf <<EOF
    server {
        listen 80;
        server_name www.rewrite.com;
    
        root /code;
        
        location /abc {
            rewrite (.*) /ccc/bbb/2.html redirect;
            #return 302 /ccc/bbb/2.html;
        }
    }
    EOF
    
    # 3.nginx配置文件语法检测,重载服务
    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    浏览器测试结果http://www.rewrite.com/abc/1.html

    image-20200923143934454


    案例二

    用户访问/2018/ccc/2.html实际上真实访问的是/2014/ccc/2.html

    http://www.rewrite.com/2018/ccc/2.html ==> http://www.rewrite.com/2014/ccc/2.html

    # 1.准备真实访问目录和文件
    [root@web01 ~]# mkdir /code/2014/ccc -p 
    [root@web01 ~]# echo "2014_ccc_2" > /code/2014/ccc/2.html
    
    # 2.nginx跳转配置
    [root@web01 ~]# vi /etc/nginx/conf.d/rewrite.conf
    server {
        listen 80;
        server_name www.rewrite.com;
    
        root /code;
        
        location /2018 {
            rewrite ^/2018/(.*)$ /2014/$1 redirect;
        }
    }
    
    # 3.nginx配置文件语法检测,重载服务
    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    浏览器测试结果http://www.rewrite.com/2018/ccc/2.html

    image-20200923144753649


    案例三

    用户访问/test实际上真实访问的是https://www.baidu.com

    http://www.rewrite.com/test ==> https://www.baidu.com

    # 1.nginx跳转配置
    [root@web01 ~]# cat > /etc/nginx/conf.d/rewrite.conf <<EOF
    server {
        listen 80;
        server_name www.rewrite.com;
        
        root /code;
        
        location /test {
            rewrite (.*) https://www.baidu.com redirect;
        }
    }
    EOF
    
    # 2.nginx配置文件语法检测,重载服务
    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    浏览器测试结果访问http://www.rewrite.com/test结果出来https://www.baidu.com


    案例四

    用户访问couese-11-22-33.html实际上真实访问的是/course/11/22/33/course_33.html

    http://www.rewrite.com/course-11-22-33.html ==> http://www.rewrite.com/course/11/22/33/course_33.html

    # 1.准备真实访问目录和文件
    [root@web01 ~]# mkdir /code/course/11/22/33 -p
    [root@web01 ~]# echo "couese-11-22-33" > /code/course/11/22/33/course_33.html
    
    # 2.nginx跳转配置
    [root@web01 ~]# vi /etc/nginx/conf.d/rewrite.conf
    server {
        listen 80;
        server_name www.rewrite.com;
        
        root /code;
    
        location /course {
             #灵活配法
             rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;
             #固定配法
             #rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
        }
    }
    
    # 3.nginx配置文件语法检测,重载服务
    [root@web01 ~]# nginx -t 
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@web01 ~]# systemctl reload nginx
    

    浏览器测试结果http://www.rewrite.com/course-11-22-33.html

    image-20200923170614725


    案例五

    http请求跳转到https,详情见https

    Rewrite伪静态

    伪静态就是将动态网页做url重写操作(即rewrite)处理成静态页面。

    • www.kevin.com/jk/fd.php?=12 ==> www.kevin.com/jk-fd-12.html

    • 动态页面:如.php、.asp、.aspx等格式,有时后跟"?"加参数来读取数据库内不同资料

    伪静态是一种可以把文件后缀改成任何可能的一种方法,比如把php文件伪静态成html文件。

    1. 从URL结构以及页面名称看,伪静态和静态页面是一样的。伪静态的页面后缀可以是html或者htm或者是目录格式
    2. 伪静态只是改变了URL的表现形式,实际上还是动态页面
    3. 静态页面可以节省服务器资源,而伪静态严格说是增加服务器资源消耗的

    WordPress的伪静态规则:

    1. 在WordPress程序后台 - 设置 - 固定链接设置
    2. 修改Nginx配置,添加如下location / {...}
    location / {
         # Nginx会检查$uri是否存在文件,然后检查目录$uri/。如果找不到目录或文件,
         # 它将执行内部重定向以/index.php将查询字符串参数作为参数传递。
         try_files $uri $uri/ /index.php?$args;
    }
    

    Nginx相关文章资料库:WordPress的永久链接

    WordPress固定链接小提示:

    • 固定链接最好是在建站时就定好;
    • 如果后期变更固定链接一定要做好301跳转,可以搜索选择Redirection插件来解决;
    • 固定链接本身并不能达到很科学的SEO效果,各种方式并无区别;
    • 不要纠结固定链接是个什么样子。

    Nginx配置WordPress官方示例(二级目录下):

    server {
        listen 80;
        server_name blog.oldboy.com;
        root /code/wordpress;
        index index.php index.html;
        client_max_body_size 100m;
    
        location ~ .php$ {
            root /code/wordpress;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param  HTTPS on;
            include        fastcgi_params;
        }
        
        location = /favicon.ico {
            log_not_found off;
            access_log off;
        }
     
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
     
        location / {
             try_files $uri $uri/ /index.php?$args;
         }
     
         location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
             expires max;
             log_not_found off;
         }
    }
    

    WordPress官方资料

    Rewrite规则参考资料

    正则表达式匹配:
    ~      为区分大小写的匹配
    ~*     不区分大小写的匹配(匹配firefox的正则同时匹配FireFox)
    !~     区分大小写的不匹配
    !~*    不区分大小写的不匹配
    
    .      匹配除换行符以外的任意字符
    w     匹配字母或数字或下划线或汉字
    s     匹配任意的空白符
    d     匹配数字
         匹配单词的开始或结束
    ^      匹配字符串的开始
    $      匹配字符串的结束
    
    *      重复零次或更多次
    +      重复一次或更多次
    ?      重复零次或一次
    {n}    重复n次
    {n,}   重复n次或更多次
    {n,m}  重复n到m次
    *?     重复任意次,但尽可能少重复
    +?     重复1次或更多次,但尽可能少重复
    ??     重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}?  重复n次以上,但尽可能少重复
    
    W     匹配任意不是字母,数字,下划线,汉字的字符
    S     匹配任意不是空白符的字符
    D     匹配任意非数字的字符
    B     匹配不是单词开头或结束的位置
    [^x]   匹配除了x以外的任意字符
    
    文件及目录匹配判断:
    -f和!-f   用来判断是否存在文件
    -d和!-d   用来判断是否存在目录
    -e和!-e   用来判断是否存在文件或目录
    -x和!-x   用来判断文件是否可执行
    
    $args             此变量与请求行中的参数相等
    $content_length   等于请求行的“Content_Length”的值。
    $content_type     等同与请求头部的”Content_Type”的值
    $document_root    等同于当前请求的root指令指定的值
    $document_uri     与 $uri 一样
    $host             与请求头部中“Host”行指定的值或是request到达的server的名字(没有Host行)一样
    $http_user_agent
    $http_cookie
    $limit_rate       允许限制的连接速率
    $remote_addr      客户端ip
    $remote_port      客户端port
    $remote_user      等同于用户名,由ngx_http_auth_basic_module认证
    $request_filename  当前请求的文件的路径名,由root或alias和URI请求组合而成
    $request_body_file
    $request_uri      含有参数的完整的初始URI
    $request_method   等同于request的method,通常是“GET”或“POST”
    $query_string     与 $args一样
    $scheme           用的协议,比如http或者https
    $server_protocol  等同于request的协议,使用“HTTP/1.0”或“HTTP/1.1”
    $server_addr      请求的服务器ip,一般获得此变量的值的目的是进行系统调用。为了避免系统调用,有必要在listen指令中指明ip,并使用bind参数。
    $server_name      请求的服务器域名
    $server_port      请求的服务器端口号
    $uri              等同于当前request中的URI,可不同于初始值,例如内部重定向时或使用index
    

    Rewrite常用示例

    http协议跳转https协议

    server {
        listen 443 ssl;
        server_name s.ssl.com;
        ssl_certificate   ssl_key/server.crt;
        ssl_certificate_key  ssl_key/server.key;
        location / {
            root /code;
            index index.html;
        }
    }
    
    server {
        listen 80;
        server_name s.ssl.com;
        return 302 https://$server_name$request_uri;
    }
    # 或者
    server {
        listen 80;
        listen 443 ssl;
        server_name s.ssl.com;
        ssl_certificate   ssl_key/server.crt;
        ssl_certificate_key  ssl_key/server.key;
        location / {
            root /code;
            index index.html;
            # 判断scheme如果是http,就跳转至https
            if ( $scheme = http ) { 
                # 实现临时重定向,若想实现永久重定向,只需要将redirect改为permanent即可。
                rewrite ^/(.*)$  https://s.ssl.com/$1  redirect;    
            }
        }
    }
    

    多目录转成参数

    abc.domian.com/sort/2 ==> abc.domian.com/index.php?act=sort&name=abc&id=2

    if ($host ~* (.*)/.domain/.com) {
        set $sub_name $1;
        rewrite ^/sort//(/d+)//?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
    }
    

    目录对换

    /123456/xxxx -> /xxxx?id=123456

    rewrite ^/(/d+)/(.+)/ /$2?id=$1 last;
    

    用户用ie访问时重定向到/nginx-ie目录:

    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /nginx-ie/$1 break;
    }
    

    目录自动加“/”

    if (-d $request_filename){
        rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
    }
    

    禁止.htaccess

    location ~//.ht {
        deny all;
    }
    

    禁止多个目录

    location ~ ^/(cron|templates)/ {
        deny all;
        break;
    }
    

    禁止以/data开头的文件

    可以禁止/data/下多级目录的请求;

    location ~ ^/data {
        deny all;
    }
    

    禁止单个目录

    location /data/ {
        deny all;
    }
    

    禁止单个文件

    location ~ /data/sql/data.sql {
        deny all;
    }
    

    设定某个文件的过期时间

    99天,不记录404错误日志

    location ~(favicon.ico) {
        log_not_found off;
        expires 99d;
        break;
    }
    

    600秒,不记录访问日志

    location ^~ /html/scripts/loadhead_1.js {
        access_log off;
        root /opt/lampp/htdocs/web;
        expires 600;
        break;
    }
    

    文件反盗链并设置过期时间

    location ~* ^.+/.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {
        valid_referers none blocked *.jb51.net *.jbzj.net localhost 1.1.1.1;
        if ($invalid_referer) {
            rewrite ^/ http://www.jb51.net/jb51.gif; # 显示一张防盗链图片
            return 412;              # 自定义http状态码412,默认为403
            break;
        }
        access_log off;
        root /opt/lampp/htdocs/web;
        expires 3d;                  # 所有文件3天的浏览器缓存
        break;
    }
    

    将多级目录下的文件转成一个文件,增强seo效果

    /job-123-456-789.html ==> /job/123/456/789.html

    rewrite ^/job-(0-9+)-(0-9+)-(0-9+)/.html$ /job/$1/$2/jobshow_$3.html last;
    

    文件或目录不存在的时候重定向:

    if (!-e $request_filename) {
        proxy_pass http://127.0.0.1;
    }
    

    访问不存在页面重定向到主页

    server  {
        listen 443 ssl;
        listen 80;
        server_name www.magedu.net;
        root /data/site1/;
        ssl_certificate /etc/nginx/ssl/magedu.net.crt;
        ssl_certificate_key /etc/nginx/ssl/magedu.net.key;
        ssl_session_cache shared:sslcache:20m;
        ssl_session_timeout 10m;
    
        location / {                  
            if ( !-f $request_filename ) {
            rewrite ^/(.*)$  https://www.magedu.net/index.html  redirect;
            }
        }
    }
    

    域名跳转

    rewrite ^/ http://www.jb51.net/;
    

    多域名转向

    if ($host ~ “c1gstudio/.net”) {
        rewrite ^(.*) http://www.jb51.net$1 permanent;
    }
    

    三级域名跳转

    if ($http_host ~* “^(.*)/.i/.c1gstudio/.com$”) {
        rewrite ^(.*) http://www.jb51.net$1;
        break;
    }
    

    域名镜像

    rewrite ^/(.*) http://www.jb51.net/$1 last;
    

    某个子目录作镜像

    location ^~ /php {
        rewrite ^.+ http://www.jb51.net/ last;
        break;
    }
    

    Rewrite匹配优先级

    1. 先执行server层的rewrite
    2. 再根据location匹配优先级匹配
    3. 再执行location下的rewriRte
    4. 最后再执行location下if配置的rewrite

    配置测试:

    [root@web01 ~]# vi /etc/nginx/conf.d/priority.conf
    server {
        listen 80;
        server_name linux.youxian.com;
        location / {
            rewrite (.*) http://www.jd.com;
        }
    
        location =/ {
            rewrite (.*) http://www.taobao.com;
        }
    
        rewrite (.*) http://www.baidu.com;
    }
    

    Rewrite推荐格式

    旧配置方法

    server {
        listen 80;
        server_name www.baidu.com baidu.com;
        if ($http_host = baidu.com){
            rewrite (.*) http://www.baidu.com$1;
        }
    }
    

    新配置方法

    server {
        listen 80;
        server_name baidu.com;
        return 302 http://www.baidu.com$request_uri;
    }
    server {
        listen 80;
        server_name www.baidu.com;
    }
    

    推荐书写格式

    server {
        listen 80;
        server_name baidu.com;
        include /etc/nginx/rewrite.conf;
    }
    server {
        listen 80;
        server_name www.baidu.com;
    }
    
    [root@lb01 ~]# cat > /etc/nginx/rewrite.conf <<EOF
    return 302 http://www.baidu.com$request_uri;
    #rewrite ^(.*)$ http://www.baidu.com redirect;
    EOF
    

    Rewrite模块

    ngx_http_rewrite_module模块用于使用PCRE正则表达式更改请求URI,返回重定向,并有条件地选择配置。

    break,if,return,rewrite,和set指令按以下顺序进行处理:

    • 在server级别,指定的该模块的指令,按顺序执行;
    • 重复:
      • location根据请求URI搜索;
      • 在找到的位置内,指定的该模块的指令,按顺序执行;
      • 如果rewrite了请求URI,则重复该循环,但不超过10次。

    break

    Syntax: 	break;
    Default:	-
    Context:	server, location, if
    

    停止处理当前ngx_http_rewrite_module指令集 。

    1. 修改配置文件,实现hn跳转至henan
    [root@web01 ~]# cat > /etc/nginx/conf.d/rewrite.conf <<EOF
    location /test1 {
          rewrite  ^/test1/(.*)$   /test2/$1 last;
    }
    location  /hn {
          rewrite  ^/hn/(.*)$     /henan/$1  break;   # 实现hn跳转到henan页面,只会在本location跳转,不会跳转至下一个location,如果/hn没有henan对应的html文件,就会提示无法找到文件。
    }
    
    location /test2 {
    default_type text/html;
        echo test2;
    }
    
    location /henan {
    default_type text/html;
        echo henan;
    }
    EOF
    
    1. 如果nginx服务端的/apps/nginx/html/目录下不新建一个henan目录及henan目录下的html文件,就会提示403错误信息,只会在本地的location跳转,不会跳转至下一个location,如果匹配到就会直接返回给用户,如果没有就会显示错误。 
    [root@web01 ~]# mkdir /apps/nginx/html/henan
    [root@web01 ~]# echo /apps/nginx/html/henan/index.html > /apps/nginx/html/henan/index.html
    
    1. 在客户端访问网页效果:
    [root@web01 ~]# curl  http://192.168.37.17/hn/
    henan
    

    if

    Syntax: 	if (condition) { ... }
    Default:	-
    Context:	server, location
    

    如果condition为true,执行大括号中指定的指令模块,并在if指令中为请求分配配置。if指令中的配置是从先前的配置级别继承的。

    if仅能做单次判断,不支持使用if else或者if elif这样的多重判断。

    条件可以是以下任意一种:

    • 变量名;如果变量的值为空字符串或"0",则为false 。

      在1.0.1版之前,任何以“ 0” 开头的字符串都被视为错误值。

    • 使用“ =”和“ !=”运算符将变量与字符串进行比较;

    • 使用“ ~”(区分大小写)和“ ~*”(不区分大小写)运算符将变量与正则表达式进行匹配。

      • 正则表达式可以包含捕获,这些捕获可用于以后在$1.. $9变量中重复引用。
      • 也可用负运算符“ !~”和“ !~*”。
      • 如果正则表达式包含“ }”或“ ;”字符,则整个表达式应用单引号或双引号引起来。
    • 使用“ -f”和“ !-f”运算符检查文件是否存在;

    • 使用“ -d”和“ !-d”运算符检查目录是否存在;

    • 使用“ -e”和“ !-e”运算符检查文件,目录或符号链接是否存在;

    • 使用“ -x”和“ !-x”运算符检查可执行文件。

    示例:

    if ($http_user_agent ~ MSIE) {
        rewrite ^(.*)$ /msie/$1 break;
    }
    
    if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
        set $id $1;
    }
    
    if ($request_method = POST) {
        return 405;
    }
    
    if ($slow) {
        limit_rate 10k;
    }
    
    if ( $scheme = http ){
        return 301 https://www.baidu.com/;
    }
    
    if ( $scheme = https ){
        echo "if ----> $scheme";
    }
    

    return

    Syntax: 	return code [text];
                return code URL;
                return URL;
    Default:	-
    Context:	server, location, if
    

    停止处理,并将指定的code

    • (204、400、402 — 406、408、410、411、413、416和500-504)返回给客户端(可携带自定义响应正文text),非标准 code 444 关闭连接而不发送响应头。
    • (301、302、303、307(1.1.16)和308(1.13.0))重定向到URL。
      • 如果将重定向URL指定为该服务器本地的URI,完整的重定向URL会根据请求方案$scheme以及server_name_in_redirectport_in_redirect指令形成。
      • URL可以将带有代码302的临时重定向的a指定为唯一参数。这样的参数应以“ http://”,“ https://”或“ $scheme”字符串开头。URL可以包含变量。

    rewrite

    Syntax: 	rewrite regex replacement [flag];
    Default:	-
    Context:	server, location, if
    

    如果指定的正则表达式与请求URI匹配,则URI将按照指定的replacement进行更改。

    rewrite指令在配置文件中按其出现的顺序依次执行。

    如果替换字符串以“ http://”,“ https://”或“ $scheme” 开头,则处理停止,并将重定向(301 code)的URL返回给客户端。

    重定向的URL是根据请求方案($scheme)以及server_name_in_redirect和port_in_redirect指令形成的。

    可选flag参数可以是以下之一:

    • last

      停止处理当前ngx_http_rewrite_module指令集, 并开始搜索与更改后的URI相匹配的新位置;

    • break

      停止处理当前ngx_http_rewrite_module指令集,直接跳转至replacement进行更改后的位置,并返回数据给客户端;

    • redirect

      重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,此重定向信息不可缓存,返回携带302 code;

    • permanent

      重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,此重定向信息可缓存,返回携带301 code。

    示例:

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

    注意:

    • 如果将这些指令放在“ /download/”位置,last则应将标志替换为 break,否则nginx将循环执行:[flag]隐含循环机制,最多循环10次,超过返回500错误。

      location /download/ {
          rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 break;
          rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  break;
          return  403;
      }
      
    • 在替换字符串的末尾添加问号,可以避免在包含新请求参数的replacement字符串后,附加先前的请求参数。

      rewrite ^/users/(.*)$ /show?user=$1? last;
      
    • 如果正则表达式包含“ }”或“ ;”字符,则整个表达式应用单引号或双引号引起来。


    rewrite_log

    Syntax: 	rewrite_log on | off;
    Default:	rewrite_log off;
    Context:	http, server, location, if
    

    ngx_http_rewrite_module模块指令处理结果记录到error_log中,notice(通知)级别


    set

    Syntax: 	set $variable value;
    Default:	-
    Context:	server, location, if
    

    为指定的variable设置valuevalue可以包含文本,变量,或他们的组合。

    示例:

    location /main {
        root /code;
        index index.html;
        default_type text/html;
        set $name magedu;
        echo $name;
        set $my_port $server_port;
        echo $my_port;
    }
    
  • 相关阅读:
    树状数组
    1424:【例题3】喷水装置
    Matrix (二分套二分
    素数筛
    快速幂
    CentOS6/7-防火墙管理
    Ubuntu15.04 python升级到python-3.6.x
    查看Linux系统用户登录日志
    [shell]查找网段内可用IP地址
    最小化安装Linux的常用配置整理
  • 原文地址:https://www.cnblogs.com/backups/p/nginx11.html
Copyright © 2020-2023  润新知