# rewrite规则

## 实现url重写以及重定向

## 场景

* Url访问跳转,支持开发设计
  * 页面添砖、兼容性支持、展示效果等
* SEO优化
* 维护
  * 后台维护、流量转发等
* 安全

## 配置语法

| rewrite |                                                                         |
| ------- | ----------------------------------------------------------------------- |
| 语法      | rewrite regex replacement \[flag]                                       |
| 默认      | ---                                                                     |
| 作用域     | server,location,if                                                      |
| 例如      | <p>将网站所有请求全部重定向一个页面  <br> rewrite ^(.\*)$ /page/maintain.html break</p> |

## 正则表达式

| 正则表达式  |                       |
| ------ | --------------------- |
| .      | 匹配除换行符以外等任意字符         |
| ?      | 重复0次或1次               |
| +      | 重复1次或更多次              |
| \*     | 匹配前面的子表达式零次或多次        |
| \d     | 匹配数字                  |
| ^      | 匹配字符串的开始              |
| $      | 匹配字符串的结尾              |
| {n}    | 重复n次                  |
| {n,}   | 重复n次或更多次              |
| \[c]   | 匹配单个字符串c              |
| \[a-z] | 匹配a-z小写字母的任意一个        |
| \\     | 转移字符                  |
| ( )    | 用于匹配括号之间的内容,通过$1、$2调用 |

### 例子:

```
   ...

   if($http_user_agebt ~ MSIE) {
       rewrite ^(.*)$ /msie/$1 break;
   }

   ...
```

## pcretest

pcretest是一个正则表达式测试工具

### 例子:

```
    $ pcretest #回车
    PCRE version 8.36 2014-09-29 #这个是命令行显示的pcre版本

       re> /(\d+)\.(\d+)\.(\d+)\.(\d+)/ #输入所要匹配的正则 然后回车
    data> 192.168.10.10
    0: 192.168.10.10
    1: 192
    2: 168
    3: 10
    4: 10
```

## flag

| flag      |                         | 备注                   |
| --------- | ----------------------- | -------------------- |
| last      | 停止rewrite检测             | last停止后重新创建一个请求，然后跳转 |
| break     | 停止rewrite检测             | break直接寻找重写后的文件      |
| redirect  | 返回302临时重定向,地址栏会显示跳转后的地址 |                      |
| permanent | 返回301永久重定向,地址栏会显示跳转后的地址 |                      |

### 例子:

```
    ...

    root /www/nginx/code/

    location ~ ^/break {
        # 这个匹配到了以后 会往 /www/nginx/code/test/ 下寻找有没有 并停止
        rewrite ^/break /test/ break;
    }

    location ~ ^/last {
     # 这个匹配到了以后会重新发起一次请求 访问 uri/test/
        rewrite ^/last /test/ last;
    }

    location /test/ {
        default_type application/json;
        return 200 '{"status":"success"}'
    }

    ...

    # 访问 kingofzihua.top/break 会返回403 
    # kingofzihua.top 是我配置的虚拟域名
    # 返回403是因为我 并没有/www/nginx/code/test/ 这个目录

    # 访问 kingofzihua.top/last 会返回{"status":"success"};
    # 因为它重新发起了一次请求 kingofzihua.top/test/ 

    location /course {
        root   /www/nginx;
        # 访问 /coutse-01-02-03.html 转化为 /coutse/01/02/coutse_03.html
        rewrite ^/coutse-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break;

        # 判断如果是Chrome浏览器就跳转到百度
        if ($http_user_agent ~* Chrome) {
            # 如果访问的匹配到nginx 就跳转到百度搜索nginx
            rewrite ^/nginx https://www.baidu.com/s?wd=nginx;
        }

        # 判断如果不是一个目录
        if (!-f $request_filename ) {
            # /index 重写为index.php?s=/index
            rewrite ^(.*)$ /index.php?s=$1 last;
        }
    }

    ...
```

## Rewrite规则优先级

* 执行server块的rewrite指令
* 执行location匹配
* 执行选定的location中的rewrite


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kingofzihua.gitbook.io/middleware-architecture-based-on-nginx/shen-du-xue-xi/rewrite-gui-ze.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
