使用 Nginx Lua 处理 POST 请求表单数据

我正在使用最新版本的 OpenResty 通过 Nginx Lua 对 POST 请求数据进行一些操作。我的测试 Lua 脚本通过 rewrite_by_lua_file 调用简单易懂,如下所示:

ngx.req.read_body();
local args = ngx.req.get_post_args();
ngx.say(args["a"]);

为了测试它,我有一个简单的 HTML 文档:

<html>
<head>
<script
 src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js">
</script>
<script>
 $(document).ready(function(){
  $('#btnPOST').click(doPOST);
  $('#btnAJAX').click(doAJAX);
 });

 function doPOST()
 {
  $.post('index.php',{a:2,b:3},afterAJAX);
 }

 function doAJAX()
 {
  var fd = new FormData();
  fd.append('a',2);
  fd.append('b',3);

  $.ajax(
        {url:'index.php',data:fd,cache:false,contentType:false,
         processData:false,
         type:'POST',success:function(d){afterAJAX(d);},error:netError});
  }

  function afterAJAX(d,e)
  {
   debugger;
   alert(d);
  }

  function netError(){alert('error');}
 </script>
</head>
 <body>
  <button id='btnPOST'>发送 POST 请求</button>
  <button id='btnAJAX'>发送 AJAX 请求</button>
 </body>
</html>

单击 POST 按钮会返回预期结果 - 提示框中显示“2”。

点击正在提交的表单的 AJAX 按钮则返回 d=nil

我不确定这是怎么回事。我怀疑问题出在发送多部分表单数据的方式上。似乎 Lua/Nginx 没有正确解析多部分分界线上的表单数据。然而,在 Lua 端应该如何处理此问题还不清楚。我非常感谢任何帮助。

点赞
用户1009249
用户1009249

单击 AJAX 按钮,将发送以下请求到 nginx。

POST /index.php HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 222
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
Origin: http://localhost:8080
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarylz2ebdJs5FUQBDut
Referer: http://localhost:8080/1.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ASP.NET_SessionId=g2cg0ewk1p1o3atzmtliqydx

------WebKitFormBoundaryJOYCopXkOqDBaqff
Content-Disposition: form-data; name="a"

2
------WebKitFormBoundaryJOYCopXkOqDBaqff
Content-Disposition: form-data; name="b"

3
------WebKitFormBoundaryJOYCopXkOqDBaqff--

请注意,请求主体不是键/值参数格式,例如 a=2&b=3

因此,ngx.req.get_post_args 无法正确解析 AJAX 请求主体,并且 ngx.say(args[a]) 输出 nil

更新

对于流读取器和解析器,您可以尝试 lua-resty-upload 项目。

2016-03-27 16:47:46