Nginx rewrite中 Query String的处理

Nginx除了能对UA进行处理,乃能对特殊的Query String进行处理。
最典型的应用就是,location进行路径匹配的时候,是没办法是用正则表达一起捕获这个路径和querstring的。那么我想真的URL里面的Query String进行不同的rewrite,应该如何处理呢?答案就是$arg变量。
Nginx里面$query_string 与$args相同,存储了所提交的所有$query_string
比如&p=2887&q=test
如果想要在nginx里面单独访问这些变量。可以这样
比如$p变量可以这样访问 $arg_p
下面是用这样一个实例讲述一下。
我准备停用WAP-T-WAP插件,但是发现Google对我站点的wap收录比较多,为了保留SEO,对wap目录进行301重定向。
要求是 如果请求中的$query_string包含"q=数字",301重新定向到首页交由index.php处理。
否则只是301重新定向到首页。

效果:


关于rewrite后面的问号,其作用是去除后面的qrerystring,不加?的话,就是这样的
比如原来的query_string是p=2887,不加问号的话 是重新定向到

http://ihipop.info/?2887&p=2887

多了一个&p=2887这样产生的 URI 不是很美观。
详见Remove query string on rewrite :http://forum.nginx.org/read.php?2,118933,118933


Nginx 内置变量表( ngx_http_variables)
变量名 版本 简要说明
$args 1.0.8 请求中的参数;
$binary_remote_addr 1.0.8 远程地址的二进制表示
$body_bytes_sent 1.0.8 已发送的消息体字节数
$content_length 1.0.8 HTTP请求信息里的"Content-Length";
$content_type 1.0.8 请求信息里的"Content-Type";
$document_root 1.0.8 针对当前请求的根路径设置值;
$document_uri 1.0.8 与$uri相同;
$host 1.0.8 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$hostname 1.0.8
$http_cookie 1.0.8 cookie 信息
$http_post 1.0.8
$http_referer 1.0.8 引用地址
$http_user_agent 1.0.8 客户端代理信息
$http_via 1.0.8 最后一个访问服务器的Ip地址。
$http_x_forwarded_for 1.0.8 相当于网络访问路径。
$is_args 1.0.8
$limit_rate 1.0.8 对连接速率的限制;
$nginx_version 1.0.8
$pid 1.0.8
$query_string 1.0.8 与$args相同;
$realpath_root 1.0.8
$remote_addr 1.0.8 客户端地址;
$remote_port 1.0.8 客户端端口号;
$remote_user 1.0.8 客户端用户名,认证用;
$request 1.0.8 用户请求
$request_body 1.0.8
$request_body_file 1.0.8 发往后端的本地文件名称
$request_completion 1.0.8
$request_filename 1.0.8 当前请求的文件路径名
$request_method 1.0.8 请求的方法,比如"GET"、"POST"等;
$request_uri 1.0.8 请求的URI,带参数;
$scheme 1.0.8 所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect;
$sent_http_cache_control 1.0.8
$sent_http_connection 1.0.8
$sent_http_content_length 1.0.8
$sent_http_content_type 1.0.8
$sent_http_keep_alive 1.0.8
$sent_http_last_modified 1.0.8
$sent_http_location 1.0.8
$sent_http_transfer_encoding 1.0.8
$server_addr 1.0.8 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 1.0.8 请求到达的服务器名;
$server_port 1.0.8 请求到达的服务器端口号;
$server_protocol 1.0.8 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$uri 1.0.8 请求的URI,可能和最初的值有不同,比如经过重定向之类的。

[download id="33" format="2"]

Author Info :
  • From:Nginx rewrite中 Query String的处理
  • URL:https://blog.ihipop.com/2012/01/2935.html
  • Please Reserve This Link,Thanks!
  • 《Nginx rewrite中 Query String的处理》上有7条评论

        1. 看你的代码应该都是mcv的框架写的。大多数这样的框架会自动转换path info
          比如index.php/js/view/1170.html

    1. 我是搜nginx $args过来的,博主的博客部分已在墙外了啊。
      我这有个问题,没搞定,想请教一下,嘿嘿。

      我想把链接 .com/?id=xxx 重写成.com/entries/xxx/ 使用rewrite ^/entries/(\d+)/$ /?id=$1 last;搞定了。
      然后想把Google已经收录的.com/?id=xxx 重定向到 .com/entries/xxx/ 使用
      if ($query_string ~* "id=(\d+)$") {
      set $id $1;
      rewrite / /entries/$id/? permanent;
      }
      也可以实现了。
      但是这两条不管那个放在前面都会出现重定向循环,不知道该怎么解决。

      需要将 .com/?id=xxx 重写成.com/entries/xxx/ 并且重定向到.com/entries/xxx/

      1. 在墙外?啥意思?我打开正常啊
        另外你这个就是一个死循环嚒。
        第一个rewrite就会产生一个$query_string包含"id=(\d+)$"的请求
        第二个又会匹配到第一个去
        你这样 你把第二个放到第一个,然后你把原来的第一个里面的last改成break试试

    发表回复

    您的电子邮箱地址不会被公开。 必填项已用 * 标注