项目里面需要用到使用NodeJs来转发HTTP POST请求,把过程记录一下:
- exports.sendEmail = function (req, res) {
- res.send(200, req.body.address);
- }
之所以能够访问body的address属性,这得益于express.js(connect)的bodyparser中间件。该中间件解析request的body,假如其content type满足某些条件的话,就尝试将其转换成javascript对象。某些条件是指:multipart, urlencoded, json。
好了,接下来看转发端的代码,为了简单起见,我直接将hard-coding的数据进行转发:
1 /** 2 * nodejs向apache发送请求,接收响应后返回到浏览器端 3 */ 4 app.get('/nodeReq', function(req,res,next){ 5 var data = { 6 age: 20, 7 name: "cici", 8 like: "shopping" 9 }; 10 data = require('querystring').stringify(data); //数据以url param格式发送 11 data = JSON.stringify(data); //数据以json格式发送 12 console.log(data); 13 var opt = { 14 method: "POST", 15 host: "localhost", 16 port: 8012, 17 path: "/php/get_data.php", 18 headers:{ 19 //"Content-Type": "application/x-www-form-urlencoded", //for url parameter 20 "Content-Type": "application/json", // for json data 21 "Content-Length": data.length 22 } 23 }; 24 25 var req = http.request(opt, function(apacheRes){//建立连接 和 响应回调 26 if(apacheRes.statusCode == 200){ 27 apacheRes.setEncoding('utf8'); 28 var body = ""; 29 apacheRes.on('data', function(recData){ body += recData;}); 30 apacheRes.on('end', function(){ res.send(body); /*发送收到的响应*/ }); 31 }else{ 32 res.send(500, "error"); 33 } 34 }); 35 req.write(data + " "); //发送请求 36 req.end(); //请求发送完毕 37 });
注意,我把content type设置成x-www-form-urlencoded,这是bodyparser所支持的了类型之一,而body的格式通过require('querystring').stringify(...)来格式化的,这个会将对象转换成诸如"address=test%40test.com&subject=test"这种格式的字符串。
另一个是用JSON.stringify()来格式化body内容,然后把content-type改为application/json格式,当然,这个也是body parser所支持的格式之一!
另外,有两个地方,我不是很清楚,一个是貌似content-length不是必须的,另一个是req.write(data+" ")的" "也不是必须的,这个有待研究。。。
补充:
bodyparser的代码在” ode_modulesexpress ode_modulesconnectlibmiddlewareodyParser.js“,它其实什么都没做,只是把解析body的任务派发给了另外3个中间件:./multipart, ./urlencoded, ./json:
- ./multipart 负责 application/x-www-form-urlencoded 类型。
- ./urlencoded 负责 multipart/form-data 类型。
- ./json 负责 application/json 类型。
用http.request发送文件给服务端, 或带参post数据到服务端
var http = require('http'); var fs = require('fs'); var queryString = require('querystring'); var boundaryKey = 'A' + new Date().getTime(); //随便加个前缀A 避免全数字作为分界符 /** * 带参数发post请求 */ function doPost(){ var opt = { host:'localhost', //注意:不用协议部分(http://) port:'80', path: '/testonly/doupload.php', //斜杠开头 method:'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} //设置content-type 头部 }; var body = ''; var req = http.request(opt, function(res){ res.statusCode == 200 && console.log('REQUEST OK..' ); res.setEncoding('utf8');//res为ClientResponse的实例,是readableStream, 设置字符编码 res.on('data', function(chunk){ body += chunk; }).on('end', function(){ console.log('Got data: ', body);//end事件中 打印全部响应数据 }); }).on('error', function(err){ console.log('error: ', err.message); }); var data = {name:'sindy', age:22}; var data1 = JSON.stringify(data); var data2 = queryString.stringify(data); //注意 querystring.stringify 和 JSON.stringify的区别 console.log(data1); console.log(data2); req.write(data2); //req为ClientRequest的实例,是writableStream,写数据到流中 req.end();//结束请求 } /** * 发送文件给服务器并带上其他表单字段数据 */ function doUpload(){ var opt = { host:'localhost', port:'80', path: '/testonly/doupload.php', method:'POST', headers: {'Content-Type':'multipart/form-data; boundary='+boundaryKey, 'Connection':'keep-alive'} //注意:上传文件时的 content-type 设置 }; var body = ''; var req = http.request(opt, function(res){ res.statusCode == 200 && console.log('REQUEST OK..' ); res.setEncoding('utf8'); res.on('data', function(chunk){ body += chunk; }).on('end', function(){ console.log('Got data: ', body);//php 返回 $_FILES 和 $_POST的内容给客户端 }); }).on('error', function(err){ console.log('error: ', err.message); }); //ClientRequest writableStream 注意:文件字段的分界符 req.write('--'+boundaryKey+' Content-Disposition:form-data; name="upfile"; filename="test.zip" Content-Type:application/x-zip-compressed'); // 1M缓冲 var fileStream = fs.createReadStream('test.zip', {bufferSize: 1024 * 1024}); fileStream.pipe(req, {end: false}); fileStream.on('end', function(){ // ::注意::文件字段内容和其他字段之间空2行,字段名和字段值之间空2行 req.write(' --'+boundaryKey+' '+'Content-Disposition: form-data; name="submit" '+'sendfile'); req.end(' --'+ boundaryKey + '--'); //注意:结束时的分界符 末尾'--' }); } // doPost(); doUpload();