>  기사  >  백엔드 개발  >  nginx 구성 위치 요약 및 재작성 규칙 작성 방법

nginx 구성 위치 요약 및 재작성 규칙 작성 방법

WBOY
WBOY원래의
2016-07-28 08:28:46964검색

기사는 "nginx 구성 위치 요약 및 다시 쓰기 규칙 작성"에서 재인쇄되었습니다.

1. 위치 일반 쓰기

예:

location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ] 
}

location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ] 
}

location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ] 
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ] 
}

location ^~ /images/ {
  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
  [ configuration D ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ] 
}

location /images/ {
  # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
  [ configuration F ] 
}

location /images/abc {
  # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
  # F与G的放置顺序是没有关系的
  [ configuration G ] 
}

location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    [ configuration H ] 
}

location ~* /js/.*/\.js
은 시작을 의미합니다. with = 완전 일치
예를 들어 A에서는 루트 디렉터리 끝에 있는 요청만 일치하고 그 뒤에는 문자열이 포함될 수 없습니다.
^~의 시작은 uri가 일반 문자열로 시작하고 일반 일치가 아님을 의미합니다.
~는 대소문자 구분 일반 일치의 시작을 의미합니다. 둔감한 일반 일치
/ 다른 일치 항목이 없으면 모든 요청이 일치합니다.
우선순위 없음:
(위치 =) > (위치 ^~ 경로) ) > (위치 ~,~ * 일반 순서) > (위치 부분 시작 경로) > (/)
위 매칭 결과
위 위치 작성 방법에 따라 다음과 같은 매칭 예가 성립됩니다.
/ -> config A
정확하고 완전한 일치, /index.html도 일치할 수 없음
/downloads/download.html -> config B
B를 일치시킨 후 아래에 일치하는 항목이 없습니다. , B
/images/1 .gif -> 구성 D
가 F와 일치하고, D로 내려가고, 아래로 내려가는 것을 중지합니다.
/images/abc/def -> config D
가장 긴 일치 G는 D로 내려갑니다.
/images/로 시작하는 모든 항목은 D와 일치하고 중지됩니다. 여기에 FG를 쓰는 것은 결코 의미가 없습니다. 일치하는 순서
/documents/document.html -> config C
는 C와 일치하며 아래에는 일치하는 항목이 없습니다. C
/documents/1.jpg -> 구성 E
를 사용하세요. C, 아래로 이동합니다. 하위 일반 패턴은 E
/documents/Abc.jpg -> config CC
와 일치하며, 가장 긴 일치는 C이고, 하향 일반 패턴 시퀀스는 CC와 일치하며 아래로 내려가지 않습니다. E
실제 사용 제안
그래서 실제 사용에서는 개인적으로 다음과 같이 일치하는 규칙 정의가 세 개 이상 있다고 생각합니다.

http://tengine.taobao.org/ book/chapter_02.html

#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
    proxy_pass http://tomcat:8080/
}
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
2. 다시 쓰기 규칙
다시 쓰기 기능은 nginx에서 제공하는 전역 변수 또는 URL 재작성과 방향 재작성을 구현하기 위해 정규식 및 플래그와 결합하여 직접 설정합니다. rewrite는 서버{}, 위치{}, if{}에만 배치할 수 있으며 http://seanlook.com/a/we/index와 같은 전달된 매개변수를 제외하고 도메인 이름 뒤의 문자열에서만 작동할 수 있습니다. .php?id=1&u=str은 /a/we/index.php에 대해서만 다시 작성됩니다. 구문 rewrite regex replacement [flag];
상대 도메인 이름이나 매개변수 문자열이 작동하는 경우 전역 변수 일치를 사용하거나 Proxy_pass 역방향 프록시를 사용할 수 있습니다.
재작성과 위치 기능은 다소 유사하며 둘 다 점프를 달성할 수 있음을 보여줍니다. 주요 차이점은 재작성은 동일한 도메인 이름 내에서 리소스를 얻기 위해 경로를 변경하는 반면 위치는 액세스 또는 역방향 프록시를 제어한다는 것입니다. 경로 클래스를 사용하여 다른 시스템에 Proxy_pass를 수행할 수 있습니다. 대부분의 경우 해당 위치에 다시 쓰기도 작성됩니다. 실행 순서는 다음과 같습니다.
서버 블록의 다시 쓰기 명령 실행
위치 일치 실행
선택한 위치에서 다시 쓰기 명령 실행
그 중 하나 단계 URI가 다시 작성되면 실제 파일을 찾을 때까지 1-3을 다시 반복하고, 루프가 10회를 초과하면 500 내부 서버 오류가 반환됩니다.
2.1 플래그 플래그
last: Apache의 [L] 표시와 동일하며 다시 쓰기 완료를 나타냅니다.
break: 현재 가상 호스트의 후속 다시 쓰기 명령 세트 실행을 중지합니다.
redirect: 302 임시 리디렉션을 반환합니다. 주소 표시줄은 점프 후 주소를 표시합니다
permanent: 301 영구 리디렉션 반환, 주소 표시줄은 점프 후 주소를 표시합니다
301 및 302는 단순히 상태 코드를 반환할 수 없기 때문에 리디렉션 URL도 있어야 합니다. 이것이 return 명령이 301,302를 반환할 수 없는 이유입니다. 여기서 last와 break의 차이점은 약간 이해하기 어렵습니다.
last는 일반적으로 서버에 작성되고 if, break는 일반적으로 위치에서 사용되는 반면
last는 다시 작성된 URL 일치, 즉 새 URL을 종료하지 않습니다. url은 서버에서 다시 이동합니다. 원패스 매칭 프로세스, break는 재작성된 매칭을 종료합니다.
break와 마지막은 후속 재작성 지침의 지속적인 실행을 구성할 수 있습니다
2.2 명령어 및 전역 변수
판단 명령어인 경우
구문은 if(condition ){...}이며, 주어진 조건을 판단합니다. true인 경우 중괄호 안의 다시 쓰기 지시문이 실행됩니다. if 조건(조건)은 다음과 같습니다.
표현식이 단순한 변수일 때 값이 비어 있거나 0으로 시작하는 문자열이면 false로 처리
변수와 내용을 직접 비교할 때는 = 또는 !=
~정규식 일치, ~*대소문자 구분 없음 일치, !~대소문자 구분 비일치
-f 및 !-를 사용합니다. f는 파일이나 디렉터리가 있는지 확인하는 데 사용됩니다.
-d 및 !-d는 디렉터리가 있는지 확인하는 데 사용됩니다.
-e 및 !-e는 파일이나 디렉터리가 있는지 확인하는 데 사용됩니다.
-x 및 !-x는 파일이나 디렉터리가 존재하는지 확인하는 데 사용됩니다. 파일이 실행 가능한지 확인합니다.

例如:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //如果cookie匹配正则,设置变量$id等于正则引用部分

if ($request_method = POST) {
    return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302

if ($slow) {
    limit_rate 10k;
} //限速,$slow可以通过 set 指令设置

if (!-f $request_filename){
    break;
    proxy_pass  http://127.0.0.1; 
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查

if ($args ~ post=140){
    rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com

location ~* \.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.com www.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盗链
}
全局变量
下面是可以用作if判断的全局变量
$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相同。
例:http://localhost:88/test1/test2/test.php
$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
2.3 常用正则
. : 匹配除换行符以外的任意字符
? : 重复0次或1次
+ : 重复1次或更多次
* : 重复0次或更多次
\d :匹配数字
^ : 匹配字符串的开始
$ : 匹配字符串的介绍
{n} : 重复n次
{n,} : 重复n次或更多次
[c] : 匹配单个字符c
[a-z] : 匹配a-z小写字母的任意一个
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
2.4 rewrite实例
例1:
http {
    # 定义image日志格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 开启重写日志
    rewrite_log on;
 
    server {
        root /home/www;
 
        location / {
                # 重写规则信息
                error_log logs/rewrite.log notice; 
                # 注意这里要用‘’单引号引起来,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
                set $image_file $3;
                set $image_type $4;
        }
 
        location /data {
                # 指定针对图片的日志格式,来分析图片类型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 图片不存在返回特定的信息
                return 404 "image not found\n";
        }
}
对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写tryfiles到新的image404 location,直接返回404状态码。
例2:
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location。

以上就介绍了 nginx配置location总结及rewrite规则写法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.