# rewrite指令

<mark style="color:blue;">**rewrite指令通过正则表达式的使用来改变URI**</mark>。可以**同时存在一个或者多个指令**，**按照顺序依次对URL进行匹配和处理**。

其语法结构为：

```nginx
rewrite regex replacement [flag];
```

其中：

* <mark style="color:blue;">**regex**</mark>，用于匹配URI的正则表达式。使用括号“（）”标记要截取的内容。
* <mark style="color:blue;">**replacement**</mark>，匹配成功后用于替换URI中被截取内容的字符串。<mark style="color:blue;">**默认情况下，如果该字符串是由“http\://”或者“https\://”开头的，则不会继续向下对URI进行其他处理，而直接将重写后的URI返回给客户端。**</mark>
* <mark style="color:blue;">**flag**</mark>，用来设置rewrtie对URI的处理行为，可以为以下标志中的一个：
  * **last**，停止继续在本location块中处理接收到的URI，并将此处重写的URI作为一个新的URI，使用各location块进行处理。**该标志将重写后的URI重新在server块中执行，为重写后的URI提供了转入到其他location块的机会**。

    示例：

    ```nginx
    location / {
        rewrite  ^(/myweb/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;
        rewrite  ^(/myweb/.*)/audio/(.*)\.*$  $1/mp3/$2.ra  last;
    }
    ```

    <mark style="color:purple;">**如果某URI在第2行被匹配成功并处理，Nginx服务器不会继续使用第3行的配置匹配和处理新的URI，而是让所有的location块重新匹配和处理新的URI。**</mark>
  * **break**，将此处重写的URI作为一个新的URI，在本块中继续进行处理。**该标志将重写后的地址在当前的location块中执行，不会将新的URI转向到其他location块**。

    ```nginx
    location /myweb/ {
      rewrite  ^(/myweb/.*)/media/(.＊)\..*$  $1/mp3/$2.mp3  break;
      rewrite  ^(/myweb/.*)/audio/(.＊)\.*$  $1/mp3/$2.ra  break;
    }
    ```

    <mark style="color:purple;">**如果某URI在第2行被匹配成功并处理，Nginx服务器将新的URI继续在该location块中使用第3行进行匹配和处理。新的URI始终是在同一个loaction块中。**</mark>
  * **redirect**，**将重写后的URI返回给客户端，状态代码为302**，指明是临时重定向URI，主要用在replacement变量不是以“http\://”或者“https\://”开头的情况下。
  * **permanent**，**将重写后的URI返回给客户端，状态代码为301**，指明是永久重定向URI。

{% hint style="info" %}

### <mark style="color:orange;">注意</mark>

URL（Uniform Resource Location，统一资源定位符）的一般格式为：<mark style="color:blue;">**scheme://主机名\[:端口号]\[/资源路径]**</mark>。

* <mark style="color:orange;">**rewrite接收到的 URI 不包含主机地址。因此，regex不可能匹配到 URI 的主机地址**</mark>：

  ```nginx
  rewrite  myweb.com  http://newweb.com/permanent;
  ```

  我们希望上面的rewrite指令重写<http://myweb.com/source是办不到的，因为**rewrite指令接收到的URI是> “/source”，不包含“myweb.com”\*\*。
* 请求 URL 中的<mark style="color:orange;">**请求参数也是不包含在rewrtie指令接收到的URI内容中的**</mark>。比如：

  ```http
  http://myweb.com/source?agr1=value1&agr2=value2
  ```

  **rewrite指令接收到的URI为 “/source”，不包含“?agr1=value1\&agr2=value2”**。
* 如果希望将 URL 中的请求参数传给重写后的URI，可以使用Nginx全局变量$request\_uri，比如：

  ```nginx
  rewrite myweb.com http://example.com$request_uri? permanent;
  ```

  **在$request\_uri变量后要添加问号“？”。**
* <mark style="color:blue;">**replacement变量中支持Nginx全局变量的使用，常用的还有$uri和$args等。**</mark>
* *

{% endhint %}

{% hint style="info" %} <mark style="color:blue;">**该指令可以在server块或者location块中配置**</mark>
{% endhint %}
