發(fā)送POST請求,相比GET會有些蛋疼藏杖,因為Node.js(目前0.12.4)現(xiàn)在還沒有直接發(fā)送POST請求的封裝将塑。發(fā)送GET的話,使用http.get
可以直接傳一個字符串作為URL蝌麸,而http.get
方法就是封裝原始的http.request
方法点寥。發(fā)送POST的話,只能使用原始的http.request
方法来吩,同時因為要設(shè)置HTTP請求頭的參數(shù)敢辩,所以必須傳入一個對象作為http.request
的第一個options
參數(shù)(而不是URL字符串)。另外弟疆,options
參數(shù)中的hostname
需要的是不帶協(xié)議的URL根路徑戚长,子路徑需要在path
屬性單獨設(shè)置。如果hostname
包含了完整的URL怠苔,通常會遇到錯誤:Error: getaddrinfo ENOTFOUND http://www.xxx.com/xxx同廉。
這里可以使用url
Module進行協(xié)助,使用url.parse
返回值的hostname
和path
屬性就可以柑司,測試代碼:
var url = require('url');console.log(url.parse('http://www.mgenware.com/a/b/c'));
輸出:
{ protocol: 'http:', slashes: true, auth: null, host: 'www.mgenware.com', port: null, hostname: 'www.mgenware.com', hash: null, search: null, query: null, pathname: '/a/b/c', path: '/a/b/c', href: 'http://www.mgenware.com/a/b/c' }
OK迫肖,hostname
和path
參數(shù)解決后,然后就是常見POST請求HTTP Header屬性的設(shè)置攒驰,設(shè)置method
為POST
蟆湖,另外如果是模擬HTML <form>
的POST請求的話,Content-Type
應(yīng)當是application/x-www-form-urlencoded
玻粪,最后別忘了Content-Length
隅津,而且,如果Content是字符串的話最好用Buffer.byteLength('字符串', 'utf8')
來獲取字節(jié)長度(而不是直接'字符串'.length
奶段,雖然使用URL編碼的ASCII字符串每個字符是1字節(jié))饥瓷。
然后就是回調(diào)的處理,這個在上篇文章中又講過痹籍,Callback中的第一個res
參數(shù)是執(zhí)行Readable Stream接口的呢铆,通過res
的data
事件來把chunk
存在數(shù)組里,最后在end
事件里使用Buffer.concat
把數(shù)據(jù)轉(zhuǎn)換成完整的Buffer
蹲缠,需要的話棺克,通過Buffer.toString
把Buffer
轉(zhuǎn)換成回應(yīng)的字符串悠垛。
完整代碼(我們使用httpbin.org做POST測試):
var querystring = require('querystring');
var url = require('url');
var http = require('http');
var https = require('https');
var util = require('util');
//POST URL
var urlstr = 'http://httpbin.org/post';
//POST 內(nèi)容
var bodyQueryStr = {name: 'mgen',id: 2345,str: 'hahahahahhaa'};
var contentStr = querystring.stringify(bodyQueryStr);
var contentLen = Buffer.byteLength(contentStr, 'utf8');
console.log(util.format('post data: %s, with length: %d', contentStr, contentLen));
var httpModule = urlstr.indexOf('https') === 0 ? https : http;
var urlData = url.parse(urlstr);
//HTTP請求選項
var opt = {hostname: urlData.hostname,path: urlData.path,method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded','Content-Length': contentLen}};
//處理事件回調(diào)
var req = httpModule.request(opt, function(httpRes) {var buffers = [];
httpRes.on('data', function(chunk) {buffers.push(chunk);});
httpRes.on('end', function(chunk) {var wholeData = Buffer.concat(buffers);
var dataStr = wholeData.toString('utf8');
console.log('content ' + wholeData);
});
}).on('error', function(err) {console.log('error ' + err);});
//寫入數(shù)據(jù),完成發(fā)送
req.write(contentStr);
req.end();
運行完畢后娜谊,會以字符串輸出HTTP回應(yīng)內(nèi)容确买。