一 rewrite、alias结合
问题:前端URL中含有参数的情况下,怎么用alias映射到本地目录?
解决:rewrite去除URL中的参数,重定向用alias处理
本地路径为:/videos/20200922/test.flv
前端URL为:http://localhost/vod/20200922/test.flv
直接使用alias可完成映射
前端URL为:http://localhost/vod?date=20200922&file=test.flv
先rewrite重定向,然后使用alias才能实现映射
简单的alias映射
location /vod/{
alias /home/videos/ ;
}
rewrite重定向后alias映射
location /vod/{
$tmp "/$arg_date/$arg_file" ;
rewrite /vod $tmp? ;
}
location /process/{
alias /home/videos/ ;
}
二 Nginx总结
1.proxy_pass、rewrite、alias、root的作用:
rewrite和proxy_pass的功能相似,用于请求重定向,重定向是在nginx内部进行的,可继续处理;
root 和 alias的功能相似,用于本地文件系统的映射,请求URL中的路径在本地文件系统中也是有效的;
感觉上:alias、root实现ftp的功能;proxy_pass、rewrite实现http的功能。
2.proxy_pass、rewrite、alias、root能够处理URL中的参数吗?
不能,nginx中对路径URI和参数args是分开处理的。
location、proxy_pass、rewrite、alias、root只能对URI处理。处理结果映射或重定向时,都会拼接上原来的参数。对于alias、root来说,就是会找不到本地文件。
$args、$arg_XXX、$query_string用于获取请求参数。
3.proxy_pass、rewrite、alias、root后面的URL或者路径,能够包含变量吗?
能够包含变量。
个人理解,nginx中只有一种变量类型:字符串。包含变量实际是进行字符串变量拼接。直接写在一起就是拼接:
set $str1 "ABC"
set $str2 "$str1 abc" # str2的值为 "ABC abc"
特别注意:个人理解nginx中很多地方,将字符串外面的引号省略了。如以下情景:
location "/test/" {
# 注意:http不能省略
proxy_pass "http://www.baidu.com";
}
location /test/ {
proxy_pass http://www.baidu.com;
}
这两个的效果是一样的,都是通过 localhost:8080/test 转到 www.baidu.com
可以将location、proxy_pass、rewrite、alias、root视为函数,后面的值都视为字符串类型参数。意识到这一点很重要,如下面这个问题
:
location /vod/{
set $var1 ""
alias /home/$var1
}
location /vod/{
set $var1 ""
alias "/home/$var1"
}
这两个都是为了拼接路径。如果没有意识到alias的参数实际上是字符串变量,简单照猫画虎
按第一种方式写,是错误的,第一种方式实际上等价于:"/home"$var,并没有实现字符串拼接,无法正常访问。
而第二种方式,正是nginx中拼接字符串的做法,可以正常访问。
4.location、proxy_pass、rewrite、alias、root后面路径的末尾带不带"/"?
得看具体场景,带不带"/"有区别且影响很大。
https://blog.csdn.net/wuhuagu_wuhuaguo/article/details/97095701
网上说:用alias时,外面的location路径末尾必须带"/",alias路径的后面也必须带"/"。这点是有问题的。
个人理解:要将整个过程分开看,location路径只用来匹配,alias负责替换并映射。
在本文要解决的情景中出现了这个问题:
请求URL:http://localhost/vod?date=20200922&file=test.flv
location /vod/ {
...
alias /.../
}
location /vod {
...
alias /.../
}
由于请求的URI为:/vod
拿这个URI对location进行匹配,根本匹配不到第一种,导致始终匹配到根路径"location /",然后报404错误。改成第二种后就能正常匹配上。
此外,proxy_pass、alias后面要不要带"/",见上面链接教程的分析。
nginx中获取query_string的方法:
http://www.ttlsa.com/nginx/nginx-var-3/
$args : 获取全部参数
$arg_XXX: 根据参数名获取参数
5.nginx中操作字符串的方法:
nginx中的字符串查找、截取功能全部都是基于正则表达式(目前看到的)。正则表达式和if语句连用,通过正则表达式中的分组匹配,根据分组的序号获得目标子串。
咦,这么说来这样也只实现了字符串查找功能啊,没有修改功能吗?
拼接功能的话,可以直接通过"$a $b"实现。
https://segmentfault.com/a/1190000002480053
if后面要空格
https://blog.csdn.net/gao_yu_long/article/details/78488457
if ($XXX ~ 正则表达式){
...
}
rewrite 只对URI起作用,不会处理或丢掉query_string,但可以用于自己再加上query_string
6.nginx中能去除URL后面的参数部分吗?
可以,通过rewrite可实现,之后可以再转发到其他代码块。
https://blog.csdn.net/weixin_34281537/article/details/91891002
三 参考
rewrite详细介绍:
https://www.cnblogs.com/dadonggg/p/7797281.html
注意:rewrite默认模式是重定向但是浏览器不显示重定向后的地址
proxy_pass详细介绍:
https://blog.csdn.net/u010433704/article/details/99945557
从这里可以很明显看出来,功能就是基于字符串替换,而且是替换(location)前面的全部和部分字符串,这里替换规则和alias、root结合起来看很明显。
Nginx中alias的作用:
https://blog.csdn.net/tuoni123/article/details/79712246
注意:不是重定向,经过alias处理后,已经是在服务器中查找文件了。特别是在Windows中使用时要理解好。
注意:
nginx不提供对字符串变量的修改,nginx本身就是对请求访问处理的,在nginx中进行这种操作可能本身就不正常吧。