引言

  Nginx是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3代理服务器。自2004年由俄罗斯程序员Igor Sysoev发布以来,Nginx因其高效的性能和低资源消耗迅速在全球范围内流行开来。如今,Nginx已经成为许多大型网站和应用的首选Web服务器和反向代理服务器。

  Nginx的设计目标是解决C10K问题,即在单台服务器上处理1万并发连接的问题。它采用了事件驱动(event-driven)和异步非阻塞(asynchronous non-blocking)的架构,使其在高并发环境下表现出色。相比于传统的Apache服务器,Nginx在处理静态内容和反向代理方面具有显著的性能优势。

  在Nginx的众多功能中,URL重写(URL Rewrite)是一个非常重要的功能。URL重写允许服务器根据预定义的规则对客户端请求的URL进行修改,从而实现各种复杂的需求。通过URL重写,网站管理员可以实现域名更换、网页跳转、防盗链等多种应用场景,极大地提升了网站的灵活性和用户体验。


1. Nginx Rewrite 概述

  Nginx不仅仅是一个高性能的HTTP服务器,它还可以作为一个功能强大的前端反向代理服务器。作为反向代理服务器,Nginx能够接收客户端的请求,并将这些请求转发到后端的服务器进行处理,然后将后端服务器的响应返回给客户端。这种架构在现代Web应用中非常常见,尤其是在需要处理大量并发请求的场景下。

  Nginx的反向代理功能使其能够在前端充当一个“网关”,屏蔽后端服务器的复杂性和细节。通过这种方式,Nginx可以实现负载均衡、缓存、SSL终端、压缩等功能,从而提高整个系统的性能和可靠性。特别是在高并发环境下,Nginx的非阻塞架构使其能够高效地处理大量并发连接,显著提升了系统的响应速度和稳定性。

Nginx作为前端反向代理服务器的角色

  Nginx不仅仅是一个高性能的HTTP服务器,它还可以作为一个功能强大的前端反向代理服务器。作为反向代理服务器,Nginx能够接收客户端的请求,并将这些请求转发到后端的服务器进行处理,然后将后端服务器的响应返回给客户端。这种架构在现代Web应用中非常常见,尤其是在需要处理大量并发请求的场景下。

  Nginx的反向代理功能使其能够在前端充当一个“网关”,屏蔽后端服务器的复杂性和细节。通过这种方式,Nginx可以实现负载均衡、缓存、SSL终端、压缩等功能,从而提高整个系统的性能和可靠性。特别是在高并发环境下,Nginx的非阻塞架构使其能够高效地处理大量并发连接,显著提升了系统的响应速度和稳定性

Rewrite的常见应用场景

  Nginx的Rewrite功能是通过ngx_http_rewrite_module模块实现的。这个模块允许服务器根据预定义的规则对客户端请求的URL进行修改,从而实现各种复杂的需求。以下是一些常见的Rewrite应用场景:

  1. 域名更换:当网站更换域名时,可以通过Rewrite规则将旧域名的请求重定向到新域名,确保用户访问不受影响。例如,将所有访问旧域名的请求重定向到新域名的对应页面。
  2. 网页跳转:根据特定条件将请求重定向到不同的页面。例如,根据用户的地理位置、设备类型或其他请求参数,将用户重定向到不同的页面或子域名。
  3. 防盗链:通过Rewrite功能,可以防止其他网站盗用资源。例如,限制只有来自特定域名的请求才能访问某些资源,其他来源的请求将被重定向到一个错误页面或替代资源。
  4. URL规范化:通过Rewrite规则,可以将不规范的URL重写为规范的格式,提升用户体验和SEO效果。例如,将带有大写字母的URL重写为小写字母,或者将带有多余斜杠的URL重写为标准格式。
  5. 动态URL伪装成静态地址:动态URL通常包含参数,不利于搜索引擎收录。通过Rewrite功能,可以将动态URL伪装成静态地址,提升搜索引擎收录效果。例如,将带有查询参数的动态URL重写为伪静态URL。

Nginx与Apache在URL重写上的效率

  Nginx和Apache是两种最常用的Web服务器,它们在处理URL重写时有不同的实现方式和性能表现。Nginx采用的是基于事件驱动的异步非阻塞架构,而Apache则采用的是基于线程或进程的阻塞架构。

  在处理URL重写时,Nginx的性能通常优于Apache,特别是在高并发环境下。Nginx的非阻塞架构使其能够同时处理大量并发连接,而不会因为某个请求的阻塞而影响其他请求的处理。这使得Nginx在处理大量并发请求时表现出色,能够高效地完成URL重写任务。

  此外,Nginx的配置文件采用的是模块化设计,Rewrite规则可以灵活地嵌入到不同的配置块中,如server块、location块等。这种设计使得Nginx的Rewrite配置更加灵活和易于管理。而Apache的Rewrite规则通常需要写在.htaccess文件中,虽然也很灵活,但在高并发环境下,.htaccess文件的频繁读取和解析会对性能产生一定的影响。

  综上所述,Nginx在处理URL重写时,性能和灵活性都优于Apache,特别是在需要处理大量并发请求的场景下,Nginx的优势更加明显。


2. Rewrite跳转场景

调整用户浏览的URL,使其更规范

  在现代Web开发中,URL的规范化是提升用户体验和SEO效果的重要手段。通过Nginx的Rewrite功能,可以将不规范的URL重写为规范的格式。例如,将带有大写字母的URL重写为小写字母,或者将带有多余斜杠的URL重写为标准格式。这样不仅可以提高用户的访问体验,还能提升搜索引擎对网站的收录效果。

  例如,假设用户访问的URL是http://example.com/SomePage/,我们希望将其重写为http://example.com/somepage/,可以使用如下的Rewrite规则:

rewrite ^/SomePage/$ /somepage/ permanent;

通过这种方式,用户访问的URL将被重定向到规范化的URL,从而提升网站的整体体验。

将动态URL伪装成静态地址

  动态URL通常包含查询参数,这种形式的URL不利于搜索引擎的收录。通过Nginx的Rewrite功能,可以将动态URL伪装成静态地址,从而提升搜索引擎的收录效果。例如,将带有查询参数的动态URL重写为伪静态URL。

  假设我们有一个动态URL http://example.com/index.php?id=123,希望将其重写为http://example.com/page/123,可以使用如下的Rewrite规则:

rewrite ^/page/([0-9]+)$ /index.php?id=$1 last;

  通过这种方式,动态URL将被伪装成静态地址,提升了搜索引擎的收录效果,同时也使得URL更加美观和易于记忆。

域名更换后旧域名跳转到新域名

  当网站更换域名时,为了确保用户访问不受影响,可以通过Nginx的Rewrite功能将旧域名的请求重定向到新域名。例如,将所有访问旧域名http://oldexample.com的请求重定向到新域名http://newexample.com。

可以使用如下的Rewrite规则:

server {
    listen 80;
    server_name oldexample.com;
    rewrite ^(.*)$ http://newexample.com$1 permanent;
}

通过这种方式,所有访问旧域名的请求将被永久重定向到新域名,确保用户能够顺利访问新网站。

根据变量、目录、客户端信息进行URL调整

  Nginx的Rewrite功能还可以根据请求中的变量、目录结构或客户端信息,动态调整URL,实现个性化的请求处理。例如,根据用户的地理位置、设备类型或其他请求参数,将用户重定向到不同的页面或子域名。

  假设我们希望根据用户的地理位置,将来自不同国家的用户重定向到不同的子域名,可以使用如下的Rewrite规则

geo $country {
    default US;
    include /etc/nginx/geoip.conf;
}

map $country $subdomain {
    US us;
    CN cn;
    default www;
}

server {
    listen 80;
    server_name example.com;
    rewrite ^(.*)$ http://$subdomain.example.com$1 permanent;
}

  通过这种方式,Nginx可以根据用户的地理位置,将请求重定向到不同的子域名,实现个性化的请求处理。

  除了根据地理位置进行URL调整外,Nginx的Rewrite功能还可以根据请求中的其他变量、目录结构或客户端信息,动态调整URL。这种灵活性使得Nginx能够满足各种复杂的需求,提供个性化的用户体验。

根据请求变量进行URL调整

  在实际应用中,我们经常需要根据请求中的某些变量来调整URL。例如,根据用户的语言偏好,将用户重定向到不同的语言版本的页面。假设我们希望根据请求头中的Accept-Language字段,将用户重定向到相应的语言版本,可以使用如下的Rewrite规则:

map $http_accept_language $lang {
    default en;
    ~zh zh;
    ~fr fr;
}

server {
    listen 80;
    server_name example.com;
    rewrite ^/(.*)$ /$lang/$1 last;
}

通过这种方式,Nginx可以根据用户的语言偏好,将请求重定向到相应的语言版本的页面。

根据目录结构进行URL调整

  有时我们需要根据请求的目录结构来调整URL。例如,将所有请求某个特定目录下的资源重定向到另一个目录。假设我们希望将所有请求/old-directory/下的资源重定向到/new-directory/,可以使用如下的Rewrite规则:

rewrite ^/old-directory/(.*)$ /new-directory/$1 permanent;

  通过这种方式,所有请求旧目录下资源的URL将被重定向到新目录,确保资源的访问路径一致。

根据客户端信息进行URL调整

  Nginx还可以根据客户端的信息(如IP地址、User-Agent等)进行URL调整。例如,根据客户端的IP地址,将特定IP段的用户重定向到特定的页面。假设我们希望将来自某个IP段的用户重定向到一个维护页面,可以使用如下的Rewrite规则:

geo $maintenance {
    default 0;
    192.168.1.0/24 1;
}

server {
    listen 80;
    server_name example.com;
    if ($maintenance) {
        rewrite ^(.*)$ /maintenance.html break;
    }
}

  通过这种方式,Nginx可以根据客户端的IP地址,将特定IP段的用户重定向到维护页面,实现灵活的访问控制。

3. Rewrite跳转实现

ngx_http_rewrite_module模块及其功能

  Nginx的Rewrite功能是通过ngx_http_rewrite_module模块实现的。这个模块提供了强大的URL重写功能,允许服务器根据预定义的规则对客户端请求的URL进行修改。ngx_http_rewrite_module模块是Nginx核心模块之一,广泛应用于各种URL重写和跳转需求。

  该模块支持使用正则表达式匹配URL,并根据匹配结果进行相应的重写操作。通过ngx_http_rewrite_module模块,网站管理员可以实现复杂的URL重写规则,满足各种业务需求。

Rewrite模块的依赖(如PCRE支持)

  ngx_http_rewrite_module模块依赖于PCRE(Perl Compatible Regular Expressions)库,用于处理正则表达式。PCRE库提供了强大的正则表达式匹配功能,使得Nginx能够高效地处理复杂的URL重写规则。

  在安装Nginx时,需要确保系统中已经安装了PCRE库。如果PCRE库未安装或版本不兼容,Nginx的Rewrite功能将无法正常工作。通常情况下,Nginx的安装包会自动包含PCRE库,但在某些情况下,可能需要手动安装或更新PCRE库。

Rewrite功能的实现方式

Nginx的Rewrite功能主要通过正则表达式和标志位来实现。以下是Rewrite功能的实现方式的详细解释

正则表达式

  正则表达式是Rewrite功能的核心,通过正则表达式可以匹配和捕获URL中的特定模式。Nginx的Rewrite规则通常包含一个正则表达式,用于匹配客户端请求的URL,并根据匹配结果进行相应的重写操作。

  例如,假设我们希望将所有以.html结尾的URL重写为以.php结尾,可以使用如下的Rewrite规则:

rewrite ^(.*)\.html$ $1.php last;

在这个规则中,正则表达式^(.*)\.html$匹配所有以.html结尾的URL,并将其重写为以.php结尾的URL。

标志位

Nginx的Rewrite规则支持使用标志位来控制规则的执行。常用的标志位包括lastbreakredirectpermanent等。每个标志位都有特定的含义和用途,以下是常用标志位的详细解释:

  • last:表示当前规则是最后一条Rewrite规则,匹配成功后立即停止执行后续的Rewrite规则,并继续处理请求。
  • break:表示匹配成功后立即停止执行当前location块中的后续Rewrite规则,但不退出location块,继续处理请求。
  • redirect:表示临时重定向,返回HTTP 302状态码,客户端会重新发起请求到新的URL。
  • permanent:表示永久重定向,返回HTTP 301状态码,客户端会重新发起请求到新的URL,并缓存重定向结果。

  例如,假设我们希望将所有以/old/开头的URL永久重定向到以/new/开头的URL,可以使用如下的Rewrite规则:

rewrite ^/old/(.*)$ /new/$1 permanent;

在这个规则中,标志位permanent表示永久重定向,返回HTTP 301状态码。

Rewrite规则的执行顺序

Nginx的Rewrite规则在请求处理过程中有特定的执行顺序。通常情况下,Rewrite规则会在location指令之前执行,但在某些情况下,Rewrite规则也可以嵌入到location块中执行。以下是Rewrite规则的执行顺序的详细解释:


  1. server块中的Rewrite规则:首先执行server块中的Rewrite规则,这些规则在location指令之前执行。
  2. location块中的Rewrite规则:如果请求匹配到某个location块,则执行该location块中的Rewrite规则。
  3. location块中的其他指令:最后执行location块中的其他指令,如proxy_pass、fastcgi_pass等。

例如,假设我们有如下的Nginx配置:

server {
    listen 80;
    server_name example.com;

    rewrite ^/old/(.*)$ /new/$1 permanent;

    location / {
        rewrite ^/foo/(.*)$ /bar/$1 last;
    }
}

  在这个配置中,首先执行server块中的Rewrite规则,将所有以/old/开头的URL永久重定向到以/new/开头的URL。然后,如果请求匹配到根location块/,则执行该location块中的Rewrite规则,将所有以/foo/开头的URL重写为以/bar/开头的URL。

  在Nginx的配置中,理解Rewrite规则的执行顺序对于正确配置URL重写至关重要。以下是一些更详细的示例和解释,以帮助更好地理解Rewrite规则的执行顺序:

示例1:简单的Rewrite规则
server {
    listen 80;
    server_name example.com;

    # Server块中的Rewrite规则
    rewrite ^/old/(.*)$ /new/$1 permanent;

    location / {
        # Location块中的Rewrite规则
        rewrite ^/foo/(.*)$ /bar/$1 last;
    }
}

  在这个示例中,首先执行server块中的Rewrite规则,将所有以/old/开头的URL永久重定向到以/new/开头的URL。然后,如果请求匹配到根location块/,则执行该location块中的Rewrite规则,将所有以/foo/开头的URL重写为以/bar/开头的URL。

示例2:嵌套的Location块
server {
    listen 80;
    server_name example.com;

    location / {
        # 根Location块中的Rewrite规则
        rewrite ^/foo/(.*)$ /bar/$1 last;

        location /bar/ {
            # 嵌套Location块中的Rewrite规则
            rewrite ^/bar/(.*)$ /baz/$1 last;
        }
    }
}

  在这个示例中,首先匹配到根location块/,并执行该location块中的Rewrite规则,将所有以/foo/开头的URL重写为以/bar/开头的URL。然后,如果请求匹配到嵌套的location块/bar/,则执行该嵌套location块中的Rewrite规则,将所有以/bar/开头的URL重写为以/baz/开头的URL。

示例3:使用if条件判断
server {
    listen 80;
    server_name example.com;

    location / {
        # 使用if条件判断的Rewrite规则
        if ($http_user_agent ~* "Mobile") {
            rewrite ^(.*)$ /mobile$1 last;
        }

        rewrite ^/foo/(.*)$ /bar/$1 last;
    }
}

在这个示例中,首先匹配到根location块/,并根据if条件判断用户代理是否包含“Mobile”。如果条件成立,则执行Rewrite规则,将所有请求重写为以/mobile开头的URL。然后,执行根location块中的其他Rewrite规则,将所有以/foo/开头的URL重写为以/bar/开头的URL。


Rewrite规则的调试和测试

在实际配置中,调试和测试Rewrite规则是确保其正确执行的重要步骤。Nginx提供了一些工具和方法来帮助调试Rewrite规则:

  1. 使用return指令:可以使用return指令来返回特定的状态码或消息,帮助调试Rewrite规则。例如:
location / {
        rewrite ^/foo/(.*)$ /bar/$1 last;
        return 200 "Rewrite rule executed";
    }
  1. 使用error_log指令:可以在Nginx配置中启用详细的错误日志,帮助调试Rewrite规则。例如:
error_log /var/log/nginx/error.log debug;

通过查看错误日志,可以了解Rewrite规则的执行过程和可能出现的问题。

  1. 使用curl命令:可以使用curl命令来测试Rewrite规则的执行情况。例如:
curl -I http://example.com/foo/test

通过查看响应头信息,可以确认Rewrite规则是否被正确执行。


4. Nginx正则表达式

常用的正则表达式元字符

  正则表达式(Regular Expression,简称regex)是一种强大的文本匹配工具,广泛应用于字符串搜索和替换。Nginx的Rewrite功能依赖于正则表达式来匹配和重写URL,因此理解和掌握正则表达式的基本语法和常用元字符是非常重要的。

  1. .(点):匹配除换行符以外的任意单个字符。例如,正则表达式a.b可以匹配aabacba1b等,但不能匹配a\nb
  2. *(星号):匹配前面的字符零次或多次。例如,正则表达式a*b可以匹配babaabaaab等。
  3. +(加号):匹配前面的字符一次或多次。例如,正则表达式a+b可以匹配abaabaaab等,但不能匹配b
  4. ?(问号):匹配前面的字符零次或一次。例如,正则表达式a?b可以匹配bab
  5. [](方括号):匹配方括号内的任意一个字符。例如,正则表达式[abc]可以匹配abc中的任意一个字符。
  6. [^](否定字符集):匹配不在方括号内的任意一个字符。例如,正则表达式[^abc]可以匹配除abc以外的任意一个字符。
  7. -(连字符):在方括号内表示字符范围。例如,正则表达式[a-z]可以匹配任意一个小写字母,[0-9]可以匹配任意一个数字。
  8. ()(圆括号):用于分组和捕获匹配的子字符串。例如,正则表达式(abc)+可以匹配abcabcabc等,并捕获匹配的子字符串abc
  9. |(竖线):表示逻辑或,用于匹配多个模式中的任意一个。例如,正则表达式a|b可以匹配ab
  10. ^(脱字符):匹配字符串的开头。例如,正则表达式^abc可以匹配以abc开头的字符串。
  11. $(美元符):匹配字符串的结尾。例如,正则表达式abc$可以匹配以abc结尾的字符串。

正则表达式在Rewrite中的应用

  在Nginx的Rewrite规则中,正则表达式用于匹配客户端请求的URL,并根据匹配结果进行相应的重写操作。以下是一些具体示例,说明如何在Rewrite规则中应用正则表达式进行URL匹配和重写:

示例1:匹配和重写文件扩展名

  假设我们希望将所有以.html结尾的URL重写为以.php结尾,可以使用如下的Rewrite规则:

rewrite ^(.*)\.html$ $1.php last;

在这个规则中,正则表达式^(.*)\.html$匹配所有以.html结尾的URL,并将其重写为以.php结尾的URL。具体来说:


  • ^表示匹配字符串的开头。
  • (.*)表示匹配任意字符零次或多次,并捕获匹配的子字符串。
  • \.html表示匹配.html,其中\是转义字符,用于匹配字面上的点字符。
  • $表示匹配字符串的结尾。
示例2:匹配和重写目录结构

  假设我们希望将所有请求/old-directory/下的资源重写为/new-directory/,可以使用如下的Rewrite规则:

rewrite ^/old-directory/(.*)$ /new-directory/$1 permanent;

在这个规则中,正则表达式^/old-directory/(.*)$匹配所有以/old-directory/开头的URL,并将其重写为以/new-directory/开头的URL。具体来说:


  • ^/old-directory/表示匹配以/old-directory/开头的字符串。
  • (.*)表示匹配任意字符零次或多次,并捕获匹配的子字符串。
  • $表示匹配字符串的结尾。
示例3:匹配和重写带有查询参数的URL

  假设我们希望将带有查询参数的动态URL重写为伪静态URL,例如将http://example.com/index.php?id=123重写为http://example.com/page/123,可以使用如下的Rewrite规则:

rewrite ^/index\.php\?id=([0-9]+)$ /page/$1 last;

在这个规则中,正则表达式^/index\.php\?id=([0-9]+)$匹配带有查询参数的动态URL,并将其重写为伪静态URL。具体来说:


  • ^/index\.php\?id=表示匹配以/index.php?id=开头的字符串,其中\是转义字符,用于匹配字面上的点字符和问号字符。
  • ([0-9]+)表示匹配一个或多个数字,并捕获匹配的子字符串。
  • $表示匹配字符串的结尾。
示例4:匹配和重写带有多个查询参数的URL

  在某些情况下,我们可能需要匹配和重写带有多个查询参数的URL。例如,将http://example.com/search.php?category=books&author=John重写为http://example.com/books/John,可以使用如下的Rewrite规则:

rewrite ^/search\.php\?category=([^&]*)&author=([^&]*)$ /$1/$2 last;

  在这个规则中,正则表达式^/search\.php\?category=([^&]*)&author=([^&]*)$匹配带有多个查询参数的URL,并将其重写为伪静态URL。具体来说:


  • ^/search\.php\?category=表示匹配以/search.php?category=开头的字符串,其中\是转义字符,用于匹配字面上的点字符和问号字符。
  • ([^&]*)表示匹配除&字符以外的任意字符零次或多次,并捕获匹配的子字符串。
  • &author=表示匹配&author=字符串。
  • ([^&]*)表示匹配除&字符以外的任意字符零次或多次,并捕获匹配的子字符串。
  • $表示匹配字符串的结尾。

正则表达式的高级应用

  除了基本的正则表达式匹配,Nginx的Rewrite功能还支持一些高级应用,如使用捕获组、反向引用和条件判断等。以下是一些高级应用的示例:

使用捕获组和反向引用

  捕获组和反向引用是正则表达式中的重要概念,允许我们在Rewrite规则中捕获和引用匹配的子字符串。例如,假设我们希望将所有以/user/开头的URL重写为以/profile/开头,并保留后续的路径,可以使用如下的Rewrite规则:

rewrite ^/user/(.*)$ /profile/$1 last;

rewrite ^/user/(.*)$ /profile/$1 last;

  在这个规则中,正则表达式^/user/(.*)$匹配所有以/user/开头的URL,并捕获后续的路径。反向引用$1表示匹配的子字符串,即捕获组中的内容。

使用条件判断

  Nginx的Rewrite功能还支持使用条件判断来控制Rewrite规则的执行。例如,假设我们希望根据用户代理(User-Agent)将移动设备的请求重写为移动版页面,可以使用如下的Rewrite规则:

if ($http_user_agent ~* "Mobile") {
    rewrite ^(.*)$ /mobile$1 last;
}

  在这个规则中,条件判断if ($http_user_agent ~* "Mobile")用于检查用户代理是否包含“Mobile”字符串。如果条件成立,则执行Rewrite规则,将所有请求重写为以/mobile开头的URL。

5. Rewrite基本操作

Rewrite命令的语法和标志位

  Nginx的Rewrite命令用于根据正则表达式匹配URL,并根据匹配结果进行重写。Rewrite命令的基本语法如下:

rewrite regex replacement [flag];
  • regex:正则表达式,用于匹配客户端请求的URL。
  • replacement:重写后的URL,可以包含反向引用。
  • flag:可选参数,用于控制Rewrite规则的执行。

常用的标志位包括:

  1. last:表示当前规则是最后一条Rewrite规则,匹配成功后立即停止执行后续的Rewrite规则,并继续处理请求。例如:
rewrite ^/old/(.*)$ /new/$1 last;
  1. break:表示匹配成功后立即停止执行当前location块中的后续Rewrite规则,但不退出location块,继续处理请求。例如:
location / {
        rewrite ^/foo/(.*)$ /bar/$1 break;
        proxy_pass http://backend;
    }
  1. redirect:表示临时重定向,返回HTTP 302状态码,客户端会重新发起请求到新的URL。例如:
rewrite ^/old/(.*)$ /new/$1 redirect;
  1. permanent:表示永久重定向,返回HTTP 301状态码,客户端会重新发起请求到新的URL,并缓存重定向结果。例如:
rewrite ^/old/(.*)$ /new/$1 permanent;

Location的分类及其匹配方式

在Nginx中,Location指令用于定义请求的处理方式。Location指令可以根据不同的匹配方式进行分类,常见的匹配方式包括:

  1. 精确匹配(=):用于精确匹配请求的URI。例如:
location = /exact {
        # 精确匹配 /exact
    }
  1. 前缀匹配(无修饰符):用于匹配以指定前缀开头的URI。例如:
location /prefix {
        # 匹配以 /prefix 开头的URI
    }
  1. 正则匹配(~ 和 ~*):用于匹配符合正则表达式的URI。~表示区分大小写匹配,~*表示不区分大小写匹配。例如:
location ~ \.php$ {
        # 区分大小写匹配以 .php 结尾的URI
    }

    location ~* \.jpg$ {
        # 不区分大小写匹配以 .jpg 结尾的URI
    }
  1. 最长前缀匹配(^~):用于匹配以指定前缀开头的URI,并且优先级高于正则匹配。例如:
location ^~ /static {
        # 匹配以 /static 开头的URI,优先级高于正则匹配
    }

Location的优先级及其匹配顺序

在Nginx中,不同类型的Location指令具有不同的优先级和匹配顺序。以下是Location指令的优先级和匹配顺序:


  1. 精确匹配(=):优先级最高,首先进行匹配。
  2. 最长前缀匹配(^~):其次进行匹配。
  3. 正则匹配(~ 和 ~*):再次进行匹配。
  4. 前缀匹配(无修饰符):最后进行匹配。

例如,假设我们有如下的Nginx配置:

server {
    listen 80;
    server_name example.com;

    location = /exact {
        # 精确匹配 /exact
    }

    location ^~ /static {
        # 最长前缀匹配 /static
    }

    location ~ \.php$ {
        # 区分大小写匹配以 .php 结尾的URI
    }

    location / {
        # 前缀匹配 /
    }
}

在这个配置中,Nginx将按照以下顺序进行匹配:

首先进行精确匹配/exact。

如果没有匹配到,则进行最长前缀匹配/static。

如果仍然没有匹配到,则进行正则匹配以.php结尾的URI。

如果以上都没有匹配到,则进行前缀匹配/


Rewrite和Location的执行顺序

在Nginx的配置中,Rewrite规则和Location指令的执行顺序对于正确配置URL重写至关重要。通常情况下,Rewrite规则会在Location指令之前执行,但在某些情况下,Rewrite规则也可以嵌入到Location块中执行。

以下是Rewrite规则和Location指令的执行顺序的详细解释:

  1. server块中的Rewrite规则:首先执行server块中的Rewrite规则,这些规则在Location指令之前执行。例如:
server {
        listen 80;
        server_name example.com;

        rewrite ^/old/(.*)$ /new/$1 permanent;

        location / {
            proxy_pass http://backend;
        }
    }
  1. location块中的Rewrite规则:如果请求匹配到某个location块,则执行该location块中的Rewrite规则。例如:
server {
        listen 80;
        server_name example.com;

        location / {
            rewrite ^/foo/(.*)$ /bar/$1 last;
            proxy_pass http://backend;
        }
    }
  1. location块中的其他指令:最后执行location块中的其他指令,如proxy_pass、fastcgi_pass等。例如:
server {
        listen 80;
        server_name example.com;

        location / {
            rewrite ^/foo/(.*)$ /bar/$1 last;
            proxy_pass http://backend;
        }
    }

  在这个示例中,首先执行server块中的Rewrite规则,将所有以/old/开头的URL永久重定向到以/new/开头的URL。然后,如果请求匹配到根location块/,则执行该location块中的Rewrite规则,将所有以/foo/开头的URL重写为以/bar/开头的URL。最后,执行location块中的proxy_pass指令,将请求转发到后端服务器。

  在实际项目中,结合具体的业务需求,灵活运用Nginx的Rewrite功能,可以显著提升网站的灵活性和用户体验。通过不断实践和优化Rewrite规则,确保网站的高效运行和良好用户体验。