Query String跟Arg的差异

前言与需求

https://rorschachchan.github.io/2018/01/09/记一次配置rewrite和return的经历/ 里记录了一次rewrite和return的故事,不过我当时在最后的return里是把域名给写死了:rewrite ^.*$ http://dvlshop.lechange.com/index.php/wap/$id$query last;

现在新的需求又来了,说域名不要写死,http://dvlshop.lechange.com/index.php/这部分要跟整个uri的state部分保持一致。

于是我这里再把整个uri贴出来,辣一下各位的眼睛:
http://dvlshop.lechange.com/index.php/wap/?
client_id=lc_mall_m&
redirect_uri=https%3A%2F%2Fdvlshop.lechange.com%2Fopenapi%2Ftrustlogin_api%2Fparse%2Fwap_trustlogin_lecheng%2Fcallback&
response_type=code& #满足条件的话把这个改成+auto+
scope=read&
state=http%3A%2F%2Fdvlshop.lechange.com%2Findex.php%2Fwap&
user=token%2Flcid_9f9lmo2u6i7hkl6t6eaodn2blmg5jbsg&
expire=1514191636&
source_type=lc_app&
nonce=cdizHO6uvSx5JK79Kmtz5RBpSi0ROhpF&signature=VeCceYCWDE6BZjIdni/68YCmhqc=%27

也就是说现在只需要变量state那点部分,那么这个时候就不能再使用$query_string了,要使用$arg。

$arg可以精确匹配变量,比如说我有一个参数(uri里?后面的那部分全叫参数):&p=你大爷&q=你大娘,用$query_string和$arg就是获取所有,而使用$arg_p就是可以获取“你大爷”。

于是说动手就动手,把nginx.conf改成了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location ~ .*\.php.*
{
include php_fcgi.conf;
include pathinfo.conf;
set $flag "0";
if ( $args ~ "source_type=lc_app" ) {
set $flag "1";
}
if ( $args ~ "(.*)response_type(.*)" ){
set $Flag "$flag$flag";
set $id $1;
set $query $2;
}
if ($Flag = "11"){
set $flag "0";
return 301 $arg_state$id+auto+$query;
}
}

但是通过日志查看,发现$arg_state得到的是/http%3A%2F%2Fdvlshop.lechange.com%2Fproduct-79.html,这就很囧了,我希望获取http%3A%2F%2Fdvlshop.lechange.com%2Fproduct-79.html(不要前面的反斜杠)或者是/product-79.html(不要中间的网站)。这可怎么办?

答案是,原生的nginx是做不到这一点,因为nginx不参与业务层逻辑方面的业务。如果说要达到改写的目的,就要搭配lua或者把nginx换成openresty。于是乎就让开发修改一下传递的state来达到目的。

扩展与补充

看到这个结果突然让我想起来一道面试题,说开发有一个模块,同时这个模块会给nginx提供几个状态码,比如状态码是111,那就是代表OK,状态码不是111,那就是代表不OK,现在想写一个语句,如果nginx获得的状态码不是111,返回一个404的页面,怎么写?

没错,答案也是“原生nginx写不了”,原因跟上面的一样,应用模块状态码是业务层的,nginx是http层的,不在一层压根就无法交流。

在这里也顺道补充一下“在浏览器中输入一个URL后都发生了什么?”,以下是一个大概流程:

  1. 浏览器向DNS服务器查找输入URL对应的IP地址;
  2. DNS服务器返回网站的IP地址;
  3. 浏览器根据IP地址与目标web服务器建立TCP连接;
  4. 发送HTTP请求;
  5. 服务器处理请求;
  6. 返回响应结果;
  7. 关闭TCP连接;
  8. 浏览器解析HTML;
  9. 浏览器布局渲染;

星爷、李丽珍、张曼玉

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------