nginx url rewriting

rewrite

grammar

serverWrite in the block of the configuration file like:

server {
    rewrite 规则 定向路径 重写类型;
}
  • Rule: It can be a string or a regular to indicate the target url to match
  • Directed path: Indicates the path to be directed after matching the rule. If there is a regular in the rule, it can be used $indexto indicate the capture group in the regular
  • Override type:
    • last : Equivalent to the Apache Reed (L) mark, indicating that the rewrite is completed, and the URL address of the browser address bar remains unchanged.
    • break; after the matching of this rule is completed, the matching is terminated, and the following rules are no longer matched, and the URL address of the browser address bar remains unchanged.
    • redirect: return 302 temporary redirection, the browser address will display the redirected URL address
    • permanent: Returns a 301 permanent redirect, and the browser address bar will display the redirected URL

Simple example

server {
    # 访问 /last.html 的时候,页面内容重写到 /index.html 中
    rewrite /last.html /index.html last;

    # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配
    rewrite /break.html /index.html break;

    # 访问 /redirect.html 的时候,页面直接302定向到 /index.html中
    rewrite /redirect.html /index.html redirect;

    # 访问 /permanent.html 的时候,页面直接301定向到 /index.html中
    rewrite /permanent.html /index.html permanent;

    # 把 /html/*.html => /post/*.html ,301定向
    rewrite ^/html/(.+?).html$ /post/$1.html permanent;

    # 把 /search/key => /search.html?keyword=key
    rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
}

The difference between last and break

Because 301 and 302 cannot simply return the status code, there must also be a redirected URL, which is why the return command cannot return 301, 302. The difference between last and break here is a little hard to understand:

  • Last is generally written in server and if, while break is generally used in location
  • last does not terminate the rewritten url matching, that is, the new url will go through the matching process from the server again, and break terminates the rewritten matching
  • Both break and last can organize and continue to execute subsequent rewrite instructions

locationOnce returned , breakit will take effect directly and stop subsequent matchinglocation

server {
    location / {
        rewrite /last/ /q.html last;
        rewrite /break/ /q.html break;
    }

    location = /q.html {
        return 400;
    }
}
  • /last/Rewrite it when accessing /q.html, then use the new urirematch, just match locatoin = /q.htmland return400
  • /breakIt is rewritten when accessing /q.html, because it is returned break, it stops directly

if judgment

It's just that the above simple rewriting often fails to meet the needs. For example, when the file does not exist, when the path contains xx and other conditions, you need to useif

grammar

if (表达式) {
}
  • When the expression is just a variable, if the value is empty or any string starting with 0 will be treated as false
  • When comparing variables and contents directly, use = or !=
  • ~regex match, ~* case-insensitive match, !~case-sensitive mismatch

Some built-in conditional judgments:

  • -f and !-f are used to determine whether a file exists
  • -d and !-d are used to determine whether a directory exists
  • -e and !-e are used to determine whether a file or directory exists
  • -x and !-x are used to determine whether the file is executable

Built-in global variables

$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相同。 

Such as:

访问链接是:http://localhost:88/test1/test2/test.php 
网站路径是:/var/www/html

$host:localhost
$server_port:88 $request_uri:http://localhost:88/test1/test2/test.php $document_uri:/test1/test2/test.php $document_root:/var/www/html $request_filename:/var/www/html/test1/test2/test.php 

example

# 如果文件不存在则返回400
if (!-f $request_filename) {
    return 400;
}

# 如果host不是xuexb.com,则301到xuexb.com中
if ( $host != "xuexb.com" ){
    rewrite ^/(.*)$ https://xuexb.com/$1 permanent;
}

# 如果请求类型不是POST则返回405
if ($request_method = POST) {
    return 405;
}

# 如果参数中有 a=1 则301到指定域名
if ($args ~ a=1) {
    rewrite ^ http://example.com/ permanent;
}

locationIt can be used in combination with rules in certain scenarios , such as:

# 访问 /test.html 时
location = /test.html {
    # 默认值为xiaowu
    set $name xiaowu;

    # 如果参数中有 name=xx 则使用该值
    if ($args ~* name=(\w+?)(&|$)) {
        set $name $1;
    }

    # 301
    rewrite ^ /$name.html permanent;
}

The above says:

  • /test.html => /xiaowu.html
  • /test.html?name=ok => /ok.html?name=ok

location

grammar

Use in serverblocks like:

server {
    location 表达式 {
    }
}

location expression type

  • If you write a path directly, it will match the path under the path
  • ~ means to perform a regular match, case sensitive
  • ~* means to perform a regular match, case-insensitive
  • ^~ means normal character match. Use prefix matching. If the match is successful, no other locations will be matched.
  • = does an exact match of ordinary characters. That is, an exact match.

priority

  1. The equals type (=) has the highest precedence. Once a match is successful, no further matches are found.
  2. ^~ type expression. Once a match is successful, no further matches are found.
  3. Regular expression types (~ ~*) have the next highest priority. If there are multiple location regexes that can match, the one with the longest regex is used.
  4. Regular string match type. Match by prefix.

Example - Fake address disguise real address

server {
    # 用 xxoo_admin 来掩饰 admin
    location / {
        # 使用break拿一旦匹配成功则忽略后续location
        rewrite /xxoo_admin /admin break; } # 访问真实地址直接报没权限 location /admin { return 403; } }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326013766&siteId=291194637