Node.js 接到从 Aapache CGI 的 Request 过来后,会把所有的 Header 参数都存到 process.env , 其中包含 NODE_PATH 、HTTP_HOST,HTTP_USER_AGENT,HTTP_ACCEPT、REQUEST_METHOD、QUERY_STRING...等
这篇主要目的是处理 GET 、 POST 、 COOKIE 、File Upload 这四种 HTTP Protocol 讯息传输的方式。
GET Param
GET 的参数会存在 process.env.QUERY_STRING,像这样「 QUERY_STRING: 'account=test'」,所以只要将 QUERY_STRING 的内容做切割,就能够很轻易的取出参数。
- o.getGET = function (p) {/*{{{*/
- var q = p.env.QUERY_STRING;
- if(!q){return ;}
- var g = q.split(/&(?=[a-z])/);
- var get = {};
- var reg = /([^=]+)=(.+)/i,t;
- var n = g.length;
- for(var i=0 ;i<n ;i++) {
- t = g[i].match(reg);
- if(t && t.length==3)
- get[t[1]] = t[2];
- }
- this.GET = get;
- }/*}}}*/
POST Param
POST 的参数比起 GET 会比较复杂一点,POST 传递的参数长度是没有限制,所以不能够存在任何的变数中,否则会造成 buffer 溢出,会有安全上的疑虑,而 POST 的内容会存在 input buffer 中,必须透过读取 buffer 的方式来操作。
透过读取 /dev/stdin 的方式,将 input buffer 的资料读进来「fs.readFileSync('/dev/stdin')」。
读到 POST 的资料后,跟 GET 一样使用 Regular Exp 的方式,将参数切割出来,存在 this.POST。
- /** param by method post**/
- o.getPOST = function(buff) {/*{{{*/
- if (!buff){return ; }
- var g = buff.split(/&(?=[a-z])/);
- var get = {};
- var reg = /([a-z0-9_\-]+)=(.+)/i,t;
- var n = g.length;
- for(var i=0 ;i<n ;i++) {
- t = g[i].match(reg);
- if(t && t.length==3)
- get[t[1]] = t[2];
- }
- this.POST = get;
- }/*}}}*/
COOKIE Param
浏览器传过来的 COOKIE 的参数会存在 process.env.HTTP_COOKIE,像这样「 HTTP_COOKIE: 'account=test; browser=ie'」
正常的 cookie 的分割方式是使用 「; 」,一个分号,再加上一个空白,所以使用 RegExp 「/; /」就能快速的切割出来。
- o.getCookies = function () {
- if (!process.env.HTTP_COOKIE) {
- this.COOKIE={};
- return;
- }
- var cookieStr = process.env.HTTP_COOKIE;
- var cookieTmp = cookieStr.split(/; /i);
- var reg = /([a-z][^=]*)=(.+)/;
- var cookieList = {};
- var n = cookieTmp.length;
- for (var i=0; i<n;i++) {
- var t = cookieTmp[i].match(reg);
- cookieList[t[1]] = t[2];
- }
- this.COOKIE = cookieList;
- }
File Upload
File Upload 的处理方式与 POST 有点像,File Upload 的资料一样是存在 input buffer 里,所以也是透过读取「 /dev/stin」这个档案。
在使用 File Upload 的 Form 表单中, HTML 都会出加上一个属性 「enctype="multipart/form-data"」
当 Form 有这个属性时,档案才会上传成功,而加了 enctype 之后,原本 POST 的参数,也全部会变成 multipart/form-data 的上传格式,不再适用於 POST 的处理,也就是说上一段的 POST Param 处理方式,是没办法接收到 「multipart」上传的资料。
使用 multipart 上传方式,在「process.env.CONTENT_TYPE」中会记录一个字串 boundary , 这代表上传内容切割的字串为何 ,例如 「boundary=------------------------------6815a6a6ad9e」,这代表上传的参数必须使用「------------------------------6815a6a6ad9e」这一串字来做切割。
multipart 上传的格式如下, 第一个是指上传 key = account ,value = john ,第二个是指上传的档名为「test.txt」,内容是「test123」
- ------------------------------6815a6a6ad9e
- Content-Disposition: form-data; name="account"
- john
- ------------------------------6815a6a6ad9e
- Content-Disposition: form-data; name="file1"; filename="test.txt"
- Content-Type: application/octet-stream
- test123
知道参数的储存方式之后,就可以写程式来实现档案上传罗,档案上传的程式码较长,我就不贴了,请看 github。
回應 (Leave a comment)