rewrite带参数的URL

时间:2022-07-22
本文章向大家介绍rewrite带参数的URL,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

背景

  • 每天都会配置rewrite来将本站的一些请求重定向到微信接口
  • 每次需要手动修改nginx的配置文件
  • 降低了工作效率且增加了出错几率

具体需求:

将类似http://xxxx.com/kefu/?link=http://xxxxxx的链接,写一个rewrite规则直接跳转到link后面的链接。

介绍

nginx的重写主要功能是实现url的重定向,将原请求进行重定向到另一个url中,我们可以通过curl命令来看返回码和location字段来验证是否成功。

  1. 301 表示永久重定向,它会告诉客户端这个地址已经永久的重定向到location所指向的地址中去了,这时会返回一个301返回码
  2. 302 表示临时重定向。

实现

之前需要手动配置,如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

location /kefu1 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/DVpQBdloK4y-2UkUrGWTTw last; } location /kefu2 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/caqMQkRD6LyfyCFtJy9RxA last; } location /kefu3 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/WdagpMMPK_pB_c629y1HPg last; } location /kefu4 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/Yous0jNzeNdoIc43KguK3w last; } location /kefu5 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/AHuhAoyGEL8z9eR2oAO_uA last; } location /kefu6 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/LuTHZQhgxaehxQdRRNtSKg last; } location /kefu7 { rewrite ^(.*)$ https://mp.weixin.qq.com/s/YkKWsMq15c7YVKtzkK091g last; } location /kefu8 { rewrite ^(.*)$ https://mp.weixin.qq.com/s/y4LBagmx3-d2Rqa-iMK1Bg last; } location /kefu9 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/9RjaevH2d3qBLko7CinXsA last; } location /kefu10 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/5_gr9mzMN9bu0O9ITp1yCA last; } location /kefu11 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/ptuiGlgnP3Sc7AVB9xrU5w last; } location /kefu12 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/yKoErWRzDAULky-kQtljOg last; } location /kefu13 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/hGunyLvL7YFvL_lKKFZYIw last; } location /kefu14 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/7jUAUrkc0PkoqWUSaVa9sQ last; } location /kefu15 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/VhCOADlSjaBQeGBSplhm_A last; } location /kefu16 { rewrite ^(.*)$ http://mp.weixin.qq.com/s/AYPhOKYfK7yRwZHRNmcr_Q last; }

公司前端修改了下程序代码,将请求做了拼接。下面看下如何将带有参数的url进行重定向。

1 2 3 4 5 6

location /kefu { if ($query_string ~* "link=(.*)") { set $link $1; rewrite ^/kefu/(.*) $link? permanent; } }

rewrite默认是不能重写带有参数的url的,但是我们可以使用args 或 query_string来实现。

测试

1 2 3 4 5 6 7 8

[root@xs_test_bk conf.d]# curl -I https://xst.bfnet.cn/kefu/?link=https://mp.weixin.qq.com/s/Y9PSFzMIWF-NgMdAugWcug HTTP/1.1 301 Moved Permanently Server: xs Date: Mon, 02 Apr 2018 12:48:30 GMT Content-Type: text/html Content-Length: 175 Connection: keep-alive Location: https://mp.weixin.qq.com/s/Y9PSFzMIWF-NgMdAugWcug

另一种方案也可实现,但是需要rewrite多次,这无疑增大了响应时间,影响了用户体验。

1 2 3 4

location /kefu { rewrite ^/kefu /kefu/$args_link? permanent; rewrite ^/kefu/(.*) $1 permanent; }

第二种方案需要先将参数改写成不带参数的请求,然后再对新的请求做处理即可。

参数后面还带有参数?

考虑这种情况,如果参数后面还会有参数该如何操作呢?例如本篇博客中的例子,可用的url为https://mp.weixin.qq.com/s/Y9PSFzMIWF-NgMdAugWcug,但是有的链接会加上其他参数,```https://mp.weixin.qq.com/s/Y9PSFzMIWF-NgMdAugWcug?vtype=subs`类似于这种的会出现这种情况,只要是要跳转的url中带有参数的会出现请求失败的情况,不加参数会正常,所以我们需要把参数去掉。

下面来分析下:

  1. link后面的url中如果有参数会请求失败
  2. 请求失败的url去掉参数后面的内容重新请求是可以的
  3. 需要使用正则把参数前的给匹配出来

例如这里我们使用Linux的pcretest来测试:

使用之前的匹配方式:

1 2 3 4

re> "link=(.*)" data> https://xst.bfnet.cn/kefu/?link=https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g&vtype=subs 0: link=https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g&vtype=subs 1: https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g&vtype=subs

修改下nginx的正则匹配:

1 2 3 4

re> "link=(.*w{22})" data> https://xst.bfnet.cn/kefu/?link=https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g&vtype=subs 0: link=https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g 1: https://mp.weixin.qq.com/s/58FyEjMxFxJnl5fe0Ozf2g

可以看出可以把参数前面的给匹配到,参数部分会过滤掉。

1 2 3 4 5 6 7

location /kefu { if ($query_string ~* "link=(.*w{22})") { set $link $1; rewrite ^/kefu/(.*) $link? permanent; } }

遇到的问题

公司运营在入库时把链接填错了,多谢了一个空格,例如:https://xst.bfnet.cn/kf/?link= https://mp.weixin.qq.com/s/JjDFj55SvZHLOq_dXvmaJw,nginx会识别成https://xst.bfnet.cn/kf/%20https://mp.weixin.qq.com/s/JjDFj55SvZHLOq_dXvmaJw

这样我们写的if判断就不能处理这种请求了,所以我们需要再加一个判断,来增加冗余性。

1 2 3 4 5 6 7 8 9 10

location /kf { if ($request_uri ~* "%20(https.*[0-9a-zA-Z-_]{22})" ){ set $link $1; rewrite ^/kf/ $link? permanent; } if ($query_string ~* "(link=|link=%20)(https.*[0-9a-zA-Z-_]{22})") { set $link $2; rewrite ^/kf/(.*) $link? permanent; } }