今天接到一个小需求

需求如下

HR:前段时间开发的新官网,之前有很多其他公司对接了我们这个官网上的某个页面,
    现在需要你写个nginx把之前他们访问的链接重定向到现在新的链接。
我:为什么不让他们直接访问现在新的这个链接?
HR:其他公司都是用的之前链接生成的二维码,扫码访问的。
HR:现在到处都在用那个二维码,替换二维码成本太大。

 因为访问的都是前端静态文件,所以一开始想到用配置nginx的静态文件有两个指令,一个root,另一个是alias

两个路径分别是

原链接:https://www..cn/xx/zxxx/xxpl/index.shtml
新链接:https://www..cn/index/pcgw/generate/web/index.html
使用root
location /xx/zxxx/xxpl/ {
	root /index/pcgw/generate/web/;
}

如果这样写,当客户端请求/xx/zxxx/xxpl/index.shtml的时候,

Nginx会把请求映射为/index/pcgw/generate/web/xx/zxxx/xxpl/index.shtml

这样明显达不到效果。

使用alias
location ^~/xx/zxxx/xxpl/ {
    alias /index/pcgw/generate/web/;
  }

如果这样写,当客户端请求/xx/zxxx/xxpl/index.shtml的时候,

Nginx会把请求映射为/index/pcgw/generate/web/index.shtml

这样看着虽然很像,但是两个静态文件的后缀名不一样,同样达不到效果。

使用rewrite

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

location ~* /xx/zxxx/xxpl/index.shtml {
    rewrite .* /index/pcgw/generate/web/index.html;
  }

^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
\+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
 \ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置
| :或运算符

 如果这样写,当客户端请求/xx/zxxx/xxpl/index.shtml的时候,

Nginx会把/xx/zxxx/xxpl/index.shtml请求的资源更改为/index/pcgw/generate/web/index.html下的资源,同一域名内更改获取资源的路径。

所以对于统一域名下,需要更改原路径获取的资源时,建议使用rewrite。