获取请求参数

上一章节,主要介绍了一下如何使用不同 location 进行协作,对 location 进行糅合,往往都是需要参数的二次调整。如何正确获取传递参数、设置参数,就是你的必修课了。本章目的是给出在 OpenResty 的世界中,我们如何正确地获取和设置请求参数。

获取请求参数

首先看一下官方 API 文档,获取一个请求的参数有两个方法:ngx.req.get_uri_argsngx.req.get_post_args,二者主要的区别是参数来源。

参考下面例子:

  1. server {
  2. listen 80;
  3. server_name localhost;
  4. location /print_param {
  5. content_by_lua_block {
  6. local arg = ngx.req.get_uri_args() -- 获取 GET 参数
  7. for k,v in pairs(arg) do
  8. ngx.say("[GET ] key:", k, " v:", v)
  9. end
  10. ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
  11. local arg = ngx.req.get_post_args() -- 获取 POST 参数
  12. for k,v in pairs(arg) do
  13. ngx.say("[POST] key:", k, " v:", v)
  14. end
  15. }
  16. }
  17. }

输出结果:

  1. ~ curl '127.0.0.1/print_param?a=1&b=2%26' -d 'c=3&d=4%26'
  2. [GET ] key:b v:2&
  3. [GET ] key:a v:1
  4. [POST] key:d v:4&
  5. [POST] key:c v:3

从这个例子中,我们可以看到两个函数 ngx.req.get_uri_argsngx.req.get_post_args 获取数据来源是有明显区别的,前者来自 uri 请求参数,而后者来自 post 请求内容。

设置请求参数

我们获取请求参数,自然是需要使用这些参数来完成业务控制目的。大家都知道,请求参数在传递过程中需要调用 ngx.encode_args 进行规则转义。

参看下面例子:

  1. location /test {
  2. content_by_lua_block {
  3. local res = ngx.location.capture(
  4. '/print_param',
  5. {
  6. method = ngx.HTTP_POST,
  7. args = ngx.encode_args({a = 1, b = '2&'}),
  8. body = ngx.encode_args({c = 3, d = '4&'})
  9. }
  10. )
  11. ngx.say(res.body)
  12. }
  13. }

输出结果:

  1. ~ curl '127.0.0.1/test'
  2. [GET] key:b v:2&
  3. [GET] key:a v:1
  4. [POST] key:d v:4&
  5. [POST] key:c v:3

与我们预期是一样的。

如果这里不调用 ngx.encode_args,可能就会比较丑了,看下面例子:

  1. local res = ngx.location.capture(
  2. '/print_param',
  3. {
  4. method = ngx.HTTP_POST,
  5. args = 'a=1&b=2%26', -- 注意这里的 %26,代表的是 & 字符
  6. body = 'c=3&d=4%26'
  7. }
  8. )
  9. ngx.say(res.body)

PS:对于 ngx.location.capture 这里有个小技巧,args 参数可以接受字符串或 Lua 表的,这样我们的代码就更加简洁直观。

  1. local res = ngx.location.capture(
  2. '/print_param',
  3. {
  4. method = ngx.HTTP_POST,
  5. args = {a = 1, b = '2&'},
  6. body = 'c=3&d=4%26'
  7. }
  8. )
  9. ngx.say(res.body)