Search code examples
ajaxnginxluamultipartform-data

POST request Form data manipulation with Nginx Lua


I am using the latest version of OpenResty to perform some manipulations on POST request data using Nginx Lua. My test Lua script, being called via a rewrite_by_lua_file call is simple

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

To test it I have a simple HTML document

<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>

Clicking the POST button gives the expected results - the alert box says '2'.

Clicking the AJAX button which is submitting a form OTH returns d=nil.

I am not sure what is going on here. I suspect the issue here is to do with the way multipart form data are sent out. It seems like Lua/Nginx is missing out on parsing the form data on the multipart boundaries. What should I do about it at the Lua end?


Solution

  • Clicking the AJAX button, the following request is sent to 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--
    

    Note that the request body is not key/value arguments format, such as a=2&b=3.
    So ngx.req.get_post_args cannot parse AJAX request body correclty, and ngx.say(args[a]) outputs nil.

    UPDATE

    For streaming reader and parser, you can try lua-resty-upload project.