nginx获取get、post请求参数_nginx获取请求参数-程序员宅基地

技术标签: nginx  # nginx  

1、获取get请求的参数

可以通过以下几种方法:

  • 在nginx配置中,通过$arg_XXX获得单个参数XXX的值
  • 在 ngx_lua 中,通过ngx.var.arg_XXX获得单个参数XXX的值
  • 在 ngx_lua 中,通过ngx.req.get_uri_args()获取所有GET请求的参数和值,返回值是一个table结构(key是参数名,value是参数值)

说明:在openresty的lua中使用原生nginx的变量,前面需要添加ngx.var,例如获取$args变量值的方法是ngx.var.args

注意:ngx.var.arg_xx与ngx.req.get_uri_args["xx"]的区别:当请求uri中有多个同名参数时,ngx.var.arg_xx返回第一个出现的值,ngx.req_get_uri_args["xx"]返回一个table,里存放了该参数的所有值。因此,ngx.req.get_uri_args属于ngx.var.arg_的增强。

看一个例子:

location  /ztest3 {
      root    html;
      index   index.html index.htm index.php;
      proxy_redirect      off;
      proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header    X-Real-IP $remote_addr;
      proxy_set_header    Host $http_host;
      proxy_http_version  1.1;
      proxy_set_header    Connection "";

      access_by_lua_block {
          if ngx.var.request_method == "GET" then
              local _a = ngx.var.arg_a
              ngx.log(ngx.ERR,"args:a".._a)

              local g_args = ngx.req.get_uri_args()
              local _args = {}
              for k,v in pairs(g_args) do
                  if type(v) == "table" then
                      table.insert(_args,k.."="..table.concat(v,"|"))
                  else
                      table.insert(_args,k.."="..v)
                  end
              end
          end
          ngx.log(ngx.ERR,"args:"..table.concat(_args,"&"))
      }
      proxy_pass          http://z_worker;
}

输入:http://.../ztest3?a=1&b=2&b=3&a=0

输出:

args:a=1

args:b=2|3&a=1|0

2、获取post请求的参数

通过nginx内建变量$request_body获取post请求体数据(get的请求体是空),即所有请求参数和值。但需要注意:The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer.(意思是只有location中用到proxy_pass,fastcgi_pass,scgi_pass命令时,该变量才有值

也可以在lua中使用ngx.req.get_body_data()、ngx.req.get_post_args()来获取post请求体数据(同样get的为空),二者的区别:前者返回字符串,后者返回table结构(key是参数名,value是参数值)

注:对于post的请求,我们无法通过$arg_XXX这种方式获取参数值;

注:对于post请求,get_body_data()和get_post_args()这两个方法都无法获取到url后面跟的参数要获取post请求的url后面参数,只能通过ngx.var.args变量来获取

注:在使用ngx.req.get_body_data()、ngx.req.get_post_args()前需要先调用ngx.req.read_body(),或者通过配置lua_need_request_body on 指令,否则会报如下错误,no request body found; maybe you should turn on lua_need_request_body

1)get_body_data例子:

location  /ztest3 {
      root    html;
      index   index.html index.htm index.php;
      proxy_redirect      off;
      proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header    X-Real-IP $remote_addr;
      proxy_set_header    Host $http_host;
      proxy_http_version  1.1;
      proxy_set_header    Connection "";

      access_by_lua_block {
          local req_body = ngx.req.get_body_data()
          ngx.log(ngx.ERR,"body:"..req_body) --a=1&b=2
      }
      proxy_pass          http://z_worker;
}

说明:get_body_data返回的是一个字符串。

2)get_post_args示例:

location  /ztest3 {
      root    html;
      index   index.html index.htm index.php;
      proxy_redirect      off;
      proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header    X-Real-IP $remote_addr;
      proxy_set_header    Host $http_host;
      proxy_http_version  1.1;
      proxy_set_header    Connection "";

      access_by_lua_block {
          if ngx.var.request_method == "POST" then
              ngx.req.read_body()

              local p_args = ngx.req.get_post_args()
              local _args = {}
              for k,v in pairs(p_args) do
                  if type(v) == "table" then
                      table.insert(_args,k.."="..table.concat(v,"|"))
                  else
                      table.insert(_args,k.."="..v)
                  end
              end
          end
          ngx.log(ngx.ERR,"args:"..table.concat(_args,"&"))
      }
      proxy_pass          http://z_worker;
}

3)对于post请求,如何获取url后的参数?

location  /ztest3 {
      root    html;
      index   index.html index.htm index.php;
      proxy_redirect      off;
      proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header    X-Real-IP $remote_addr;
      proxy_set_header    Host $http_host;
      proxy_http_version  1.1;
      proxy_set_header    Connection "";

      access_by_lua_block {
          function mysplit (inputstr, sep)
             if sep == nil then
                sep ="%s"
             end
             local t={}
             for str in string.gmatch(inputstr,"([^"..sep.."]+)") do
                table.insert(t, str)
             end
             return t
          end

          if ngx.var.request_method == "POST" then
              ngx.req.read_body()
              --post args
              local p_args = ngx.req.get_post_args()
              
              --url args
              local g_args = ngx.var.args
              local gg_args = {} --将url args放到table中,key是参数名,val是参数值
              if g_args and #g_args > 0 then
                  local g_args_tab = mysplit(g_args,"&")
                  for k,v in pairs(g_args_tab) do
                    local kv = mysplit(v,"=")
                    gg_args[kv[1]]=kv[2]
                  end
              end
              local _args = {}
              for k,v in pairs(gg_args) do
                  p_args[k] = v
              end

              local _args = {}
              for k,v in pairs(p_args) do
                  if type(v) == "table" then
                      table.insert(_args,k.."="..table.concat(v,"|"))
                  else
                      table.insert(_args,k.."="..v)
                  end
              end
          end
          ngx.log(ngx.ERR,"args:"..table.concat(_args,"&"))
      }
      proxy_pass          http://z_worker;
}

4)一点说明:

通过ngx.req.get_uri_args()和ngx.req.get_post_args()方法获取get、post请求的参数时,返回的都是一个table结构,key是参数名,value是参数值,相当于一个map结构,对于这种table,无法使用table.concat方法来输出,所以,通常是定义一个table数组,然后是用for遍历参数table,拼接好key和value放到数组中,最后再通过table.concat方法输出数组;例如:

local g_args = ngx.req.get_uri_args()
    local _args = {}
    for k,v in pairs(g_args) do
        if type(v) == "table" then
            table.insert(_args,k.."="..table.concat(v,"|"))
        else
            table.insert(_args,k.."="..v)
        end
    end
end
ngx.log(ngx.ERR,"args:"..table.concat(_args,"&"))

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/liuxiao723846/article/details/117755966

智能推荐

linux查看端口命令_liunx中如何查端口号命令-程序员宅基地

文章浏览阅读1.4k次。netstat -an|grep 80 查看80端口进程列表_liunx中如何查端口号命令

jmeter学习记录(1)接口之间的动态关联--同一个线程组_jmeter中线程组session一致-程序员宅基地

文章浏览阅读699次。多个http请求处于同一个线程组内,可以通过正则表达式提取数据(必要时需要用v函数拼接),然后直接引用变量到下一个接口即可一、业务场景:测试过程中,有时下一个接口需要用到上一个接口的参数,我们要按照业务逻辑进行动态关联。做接口测试时候,尤其碰到某个接口需要用到上一个接口的数据,那我们就需要用到提取器来提取我们需要的数据,然后为下一个接口所用,其实就是在动态关联的时候需要用到。我最近在做接口测试过程中,正好用到了正则表达式提取数据和使用v函数拼接后,在下个接口中引用变量的场景,把整个过程记录下来,免得_jmeter中线程组session一致

libcurl 的 curl_easy_setopt()_curlopt_ssl_verifypeer-程序员宅基地

文章浏览阅读836次。CURL *hCurl = curl_easy_init();curl_easy_setopt(hCurl, CURLOPT_SSL_VERIFYPEER, 1L);curl_easy_setopt(hCurl, CURLOPT_SSL_VERIFYHOST, 2L);1、HTTPS相关(1)CURL_VERIFY_PEER默认值为1,该参数表示是否验证HTTPS证书的合法性,就是用第三方证书机构颁发的CA数字证书来解密服务端返回的证书,来验证其合法性。可在编译时就将CA数字证书编译进去,._curlopt_ssl_verifypeer

机器视觉工业缺陷检测的那些事(一、光源)_1.单选题对于表面不反光物体,采用下列哪种入射角度的光源比较好a高角度照射b-程序员宅基地

文章浏览阅读1.4w次,点赞48次,收藏324次。机器视觉工业缺陷检测的那些事(一) 视觉工业检测大体分为工件尺寸测量与定位,和表面缺陷检测,及各种Logo标识的检测与识别等。尺寸测量主要是检测物体的长、宽、高,比较常见主要是物体的二维尺寸(宽和高)检测。表面缺陷检测主要是物体表面局部物理或者化学性质不均匀的区域,比较常见的有金属或者塑料制品表面的划痕(如:手机壳/屏幕表面的划痕)、斑点和孔洞(如:PCB板漏了焊点或者表面多了焊点),纸张表面的色差、脏污点、破损,纸制品表面的压痕、凸起,玻璃等非金属制品表面的杂质、破损、污点、平整度等..._1.单选题对于表面不反光物体,采用下列哪种入射角度的光源比较好a高角度照射b

AO4621-VB一款N+P—Channel沟道SOP8的MOSFET晶体管参数介绍与应用说明-程序员宅基地

文章浏览阅读123次,点赞4次,收藏2次。在不同的栅极-源极电压下,低RDS(ON)值分别为28mΩ和51mΩ,确保高效的功率管理。利用其高电压额定值、电流承载能力和低导通电阻,AO4621-VB为不同行业和应用提供了一种多功能的功率管理解决方案。4. 电池管理:在电动车辆、太阳能系统和便携设备等电池管理系统中,AO4621-VB可以处理高电流并提供可靠性能。1. 电机控制:AO4621-VB可用于电器、机器人和工业机械等电机控制电路,具有高电流承载能力和低导通电阻。5. 音频放大器:可用于音箱和耳机等音频放大电路,确保低失真和高保真音频输出。

北斗GPS车辆监控管理系统_北斗设备管理字段-程序员宅基地

文章浏览阅读335次。监控中心是在整个系统的“神经中枢”,集中实现监控、调度、接/处警,图像处理功能和其他信息服务,并对整个系统的软硬件进行协调、管理。●防盗报警:设备提供和原车防盗器对接的自定义检测线束,防盗器发出盗,报警数据上传到中心。●(可选)自定义报警:由用户根据需要连接各种检测开关,触发报警,例如防盗器报警。●自定义报警:支持1-2路自定义报警,如卸料是报警,车辆要接检测开关;●自定义报警:支持1-2路自定义报警,如卸料是报警,车辆要接检测开关;●紧急报警:驾驶员危险时按报警开关报警,中心必须人工干预才能取消;_北斗设备管理字段

随便推点

Oracle 分析函数over,列转行函数pivot理解及综合运用(报表中的小计和合计)_oracle转置函数pivot-程序员宅基地

文章浏览阅读3.1k次。Oracle合计,根据列值条件进行多条件统计。_oracle转置函数pivot

跨域资源共享CORS漏洞_cors漏洞利用-程序员宅基地

文章浏览阅读1.3w次,点赞5次,收藏26次。0x01 漏洞简介跨域资源共享(CORS)是一种放宽同源策略的机制,它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制,以使不同的网站可以跨域获取数据,目前已经被绝大多数浏览器支持,并被主流网站广泛部署使用。跨域资源共享 CORS 漏洞主要是由于程序员配置不当,对于 Origin 源校验不严格,从而造成跨域问题,攻击者可以利用 CORS 错误配置漏洞,从恶意网站跨域读取受害网站的敏感信息。这里只做简单介绍,关于 CORS 漏洞的详细分析可以点击_cors漏洞利用

hdu 4512 吉哥系列故事——完美队形I(最长上升公共子序列)-程序员宅基地

文章浏览阅读609次。题意:给出n个人的身高,求这些人中连续的且满足对称、从做到中心递增的最大人数。题解:很明显,想到将序列倒序,然后两个串进行匹配最大上升公共子序列注意两点:一、像这样的23232 最长是3个人,所以匹配的二维循环中j最大不能超过n-i+1;二、要单独判断奇数偶数的匹配,否则奇数匹配结果会多1;#include#include#include#include#inc

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boo-程序员宅基地

文章浏览阅读3.6k次,点赞8次,收藏7次。一、除了像别人所说的索引问题,如索引不能用浮点数。二、还有一种可能是你原来pandas.DataFrame的数据已经转换成numpy.ndarray了,然后还在使用当时的表头如data[‘score’],这肯定是不行的,需要使用data = pd.DataFrame(data, columns=feature_col)来转换为dataframe继续使用。其中feature_col是你原来dataframe的表头,可以在原来是pandas.Dataframe格式时用feature_col = data._indexerror: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`n

c语言中e什么作用是什么,c语言中%e是什么意思-程序员宅基地

文章浏览阅读1.2w次,点赞5次,收藏15次。满意答案yeye_pig2019.11.25采纳率:40%等级:9已帮助:614人c语言%e的意思是:以指数形式输出实数。指针的值是语言实现(编译程序)相关的,但几乎所有实现中,指针的值都是一个表示地址空间中某个存储器单元的整数。printf函数族中对于%p一般以十六进制整数方式输出指针的值,附加前缀0x。示例:inti=1;printf("%p",&i);相当于inti=1;pr..._c语言%e

学习Android的第十六天-程序员宅基地

文章浏览阅读893次,点赞19次,收藏23次。Android 自定义 Adapter在中我们知道了啥是 Adapter,也知道了 Adapter 的家族体系,也用过了几个Adapter。本篇文章,我们就来自己实现一个 Adapter。要实现自定义的 Adapter,通常继承自 BaseAdapter 类,并重写其中的方法来适配你的数据源。首先,我们要做的就是要了解我们到底要重写哪些方法,因为 BaseAdapter 实现了 ListAdapter 和 SpinnerAdapter 接口,而这两个接口又继承自 Adapter。