青岛网站建设博采网络广州市手机网站建设怎么样
博文目录
 
文章目录
- URL 与 URI
 - 匹配规则
 - 案例说明
 
- 转发规则
 - 响应静态资源
 - 案例说明
 
- 转发动态代理
 - 案例说明
 - 案例说明
 
URL 与 URI
通常, 一个 URL 由以下部分组成
scheme://host:port/path?query#fragment
- scheme: 协议, 如 http, https, ftp 等
 - host; 主机名或 IP 地址
 - post: 端口, 80 可省略
 path:要访问的资源, 从 port 后面的 / 开始, 到 query 前面的 ? 结束, 如 /demo/user/list- query: 可选, 查询字符串, 用于向服务器传递参数, 参数之间用 & 符号分隔
 - fragment: 可选, 标识文档中的特定位置, 常用于锚点链接
 
URI 就是 除去 scheme, host, post 剩余的部分, 以 / 开头, 如 /demo/user/list?name=王#test
匹配规则
- Nginx Location
 - Beginner’s Guide
 - How nginx processes a request
 
location [ = | ~ | ~* | ^~ ] uri { ... }
Location 常用配置有两种, 一种叫做 前缀配置, 一种叫做 正则配置
- 前缀配置: 
location /,location = /,location ^~ /,location /test,location = /pvw,location ^~ /demo/user/list - 正则配置: 
location ~ \.(gif|jpg|jpeg)$,location ~* \.(gif|jpg|jpeg)$ 
还有一种以 @ 开头的被称为 Named Location, 这种不能用于常规请求处理, 而是用于请求重定向
Nginx 会将 URL 做如下规范化处理, 然后再根据 Location 配置, 开始尝试匹配
- 解码以 
%XX形式编码的文本 - 解析 
.和..相对路径组件 - 将相邻的多个 
/压缩为单个斜杠 
Nginx 用请求的 URI 部分与 location 做匹配与响应或转发, 如果 URI 不存在(如: 请求 URL 为 http://host:port), 则认为 URI 为 /
- 先找前缀配置, 判断 URI 是否以配置的前缀开头, 是的话就匹配到了, 如果匹配到多个前缀配置, 则取前缀最长的这个作为保底配置 
- 若匹配到的最长前缀配置是以 
^~开头的, 则匹配搜索将终止 - 此外, 以 
=开头的是精确匹配, 只匹配 URI 和 location 前缀完全相同的情况, 若匹到了精确匹配, 则匹配搜索将终止 
 - 若匹配到的最长前缀配置是以 
 - 再找正则配置, 按配置文件从上到下的顺序逐一匹配, 在首次匹配到后终止匹配搜索, 如果没有匹配到, 则使用先前找到的前缀配置 
- 以 
~开头, 表示区分大小写 - 以 
~*开头, 表示不区分大小写 
 - 以 
 - 如果前缀配置也没有匹配的, 则匹配失败, 返回 404
 
案例说明
location = / {[ configuration A ]
}
location / {[ configuration B ]
}
location /documents/ {[ configuration C ]
}
location ^~ /images/ {[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {[ configuration E ]
}
 
http://host:port, 匹配到 A, 精确匹配, 搜索终止http://host:port/index.html, 匹配到 B, 前缀配置里找到 B, 正则配置里没找到, 所以最终使用 Bhttp://host:port/documents/index.html, 匹配到 C, 前缀配置里找到 B 和 C, C 长将 C 设为候选, 正则配置里没找到, 所以最终使用 Chttp://host:port/images/1.gif, 匹配到 D, 前缀配置里找到 B 和 D, D 长将 D 设为候选, 因 D 以^~开头, 搜索终止, 最终使用 Dhttp://host:port/documents/1.jpg, 匹配到 E, 前缀配置里找到 B 和 C, C 长将 C 设为候选, 正则配置里找到 E, 搜索终止, 最终使用 E
转发规则
响应静态资源
请求的 URI 会被添加到 root 指定的路径后, 在本地文件系统上形成请求文件的路径
# 匹配到 / 的, 服务器发送 /data/www 目录 + Path 路径 的文件
location / {root /data/www;
}
# 匹配到 /images/ 的, 服务器发送 /data 目录 + Path 路径 的文件
location /images/ {root /data;
}
 
案例说明
- http://host:port/a/b.gif 
- 请求 URI 为 /a/b.gif
 - 响应文件为 /data/www/a/b.gif
 
 - http://host:port/images/a/b.gif 
- 请求 URI 为 /images/a/b.gif
 - 响应文件为 /data/images/a/b.gif
 
 
转发动态代理
Nginx proxy_pass
-  
无需关心 location 后面的前缀是否以 / 结尾, 因为只有一种无关紧要的特殊情况, 绝大多数时候, 是否以 / 结尾没有区别 -  
需要关心的是 proxy_pass 后面指定的 URL 中是否有 URI 部分. 即使端口后面只有 /, 那也是有 URI- 有: 把请求 URI 中与 location 配置匹配的部分剔除掉, 然后拼到 proxy_pass 指定的 URL 后面
 - 无: 把请求 URI 直接拼到 proxy_pass 指定的 URL 后面 
- 通过这种方式可以魔改请求 URL, 达到隐藏真实 URL 的效果
 
 
 -  
除此之外, 还有 3 个例外情况
- location 使用正则或者 Named (@) 时, Nginx 无法确定要替换的请求 URI 中的哪一部分, 这时候 proxy_pass 后面不能带 URI
 - 使用 rewrite 指令修改了请求的 URI 时, proxy_pass 指令中的 URI 会被忽略, 转发服务器将收到修改后的完整请求 URI
 - 如果在 proxy_pass 指令中使用了 URI 变量, 它将原封不动地传递给转发服务器,替换原始的请求 URI 
- 例如,在 
proxy_pass http://127.0.0.1$request_uri;中,$request_uri 变量将被替换为原始请求的 URI 
 - 例如,在 
 
 
案例说明
location /test {proxy_pass http://localhost:8080/demo;
}
location /foo/bar {proxy_pass http://localhost:8080;
}
location /a {proxy_pass http://localhost:8080/;
}
location /b/c {proxy_pass http://localhost:8080/demo;
}
 
- http://host:port/test/a/b/c 
- 请求 URI 是 
/test/a/b/c - 匹配到 
location /test - proxy_pass 后面的 url 有 uri 部分, uri 为 
/demo - 把匹配到 location 的 uri 开头部分的 
/test剔除, 剩余/a/b/c - 拼到 proxy_pass 指定的 url 后面, 最终转发到 
http://localhost:8080/demo/a/b/c 
 - 请求 URI 是 
 - http://host:port/foo/bar/a/b 
- 请求 URI 是 
/foo/bar/a/b - 匹配到 
location /foo/bar - proxy_pass 后面的 url 无 uri 部分
 - 拼到 proxy_pass 指定的 url 后面, 最终转发到 
http://localhost:8080/foo/bar/a/b 
 - 请求 URI 是 
 - http://host:port/a/b/c 
- 请求 URI 是 
/a/b/c - 匹配到 
locataion /a - proxy_pass 后面的 url 有 uri 部分, uri 为 
/ - 把匹配到 location 的 uri 开头部分的 
/a剔除, 剩余/b/c - 拼到 proxy_pass 指定的 url 后面, 最终转发到 
http://localhost:8080//b/c 
 - 请求 URI 是 
 - http://host:port/b/c/d 
- http://localhost:8080/demo/d
 
 
案例说明
后端服务为 http://springboot:8080/demo/user/list
# http://localhost/demo/user/list, 通
location /demo {proxy_pass http://springboot:8080;
}
# http://localhost/demo/user/list, 通
location /demo/user {proxy_pass http://springboot:8080;
}# http://localhost/test/user/list, 通
location /test {proxy_pass http://springboot:8080/demo;
}
# http://localhost/a/b/user/list, 通
location /a/b {proxy_pass http://springboot:8080/demo;
}
# http://localhost/a/b/c/list, 通
location /a/b/c {proxy_pass http://springboot:8080/demo/user;
}# http://localhost/demo/user/list, 通
location /demo {proxy_pass http://springboot:8080$request_uri;
}
