Skip to content

Instantly share code, notes, and snippets.

@dontcry2013
Last active August 10, 2018 02:57
Show Gist options
  • Save dontcry2013/9df07be9dd57db20cba8 to your computer and use it in GitHub Desktop.
Save dontcry2013/9df07be9dd57db20cba8 to your computer and use it in GitHub Desktop.
node.js http tool to handle GBK encoding
/**
* @fileOverview http请求的工具操作集,包含请求超时时间设置
* @module tool/httpHelper
*/
var http = require('http');
var https = require('https');
var qs = require('querystring');
var iconv = require('iconv-lite');
var BufferHelper = require('bufferhelper');
/**
* @exports tool/httpHelper
*/
var httpHelper = {
/**
* @description 发起远程请求的基础方法
* @param {Object} options 请求选项
* @param {String} [options.protocol='http'] 请求协议
* @param {String} [options.method='get'] 请求方法,get、post...
* @param {Object=} options.headers 请求头
* @param {String=} options.encode 请求数据的编码格式,如果是gbk,使用escape编码
* @param {Boolean=} [options.json=false] 发送的是否json数据
* @param {Boolean=} [options.buffer=false] 是否直接返回二进制数据
* @param {Number=} timeout 超时时间,单位为毫秒
* @param {Object=} data 请求发送的数据对象
* @param {RequestCallback} callback 处理请求响应的回调方法,查看 {@link RequestCallback}
* @param {String} [encoding='utf-8'] 编码格式
*/
request: function (options, timeout, data, callback, encoding) {
var httpLib = http;
if (options.protocol && options.protocol === 'https:') {
httpLib = https;
}
var content = {};
if (options.json) {
content = JSON.stringify(data);
} else {
content = (options.encode && options.encode.toLocaleLowerCase() == 'gbk') ? qs.stringify(data, null, null, {encodeURIComponent: escape}) : qs.stringify(data);
}
if (options.method.toLowerCase() === 'post') {
options.headers = options.headers || {};
options.headers['Content-Type'] = options.json ? 'application/json' : 'application/x-www-form-urlencoded';
options.headers['Content-Length'] = Buffer.byteLength(content);
}
/** 为true时直接返回数据流 */
options.buffer = options.buffer || false;
var req = httpLib.request(options, function (res) {
var bufferHelper = new BufferHelper();
res.on('data', function (chunk) {
bufferHelper.concat(chunk);
});
res.on('end', function () {
var _data;
if (options.buffer) {
_data = bufferHelper.toBuffer();
}
else {
if (typeof encoding != 'undefined' && encoding !== null) {
_data = iconv.decode(bufferHelper.toBuffer(), encoding);
} else {
_data = iconv.decode(bufferHelper.toBuffer(), 'utf-8');
}
}
callback(null, _data, res, req);
});
});
req.on('error', function (err) {
callback(err);
});
req.write(content);
if (timeout && timeout > 0) {
req.setTimeout(timeout, function () {
callback(new Error('request timeout'), '');
});
}
req.end();
},
/**
* @description 以GET的方式发起远程请求
* @param {String} url 请求地址
* @param {Number=} timeout 超时时间,单位为毫秒
* @param {RequestCallback} callback 处理请求响应的回调方法,查看 {@link RequestCallback}
* @param {String} [encoding='utf-8'] 编码格式
* @param {Object=} header 请求头对象
*/
get: function (url, timeout, callback, encoding, header) {
var options = require('url').parse(url);
options.method = 'GET';
if (header) {
options.headers = header;
}
this.request(options, timeout, {}, callback, encoding);
},
/**
* @description 以POST的方式发起远程请求
* @param {String} url 请求地址
* @param {Number=} timeout 超时时间,单位为毫秒
* @param {Object=} data 请求发送的数据对象
* @param {RequestCallback} callback 处理请求响应的回调方法,查看 {@link RequestCallback}
* @param {String} [encoding='utf-8'] 编码格式
* @param {Object=} header 请求头对象
* @param {String=} reqEncoding 请求数据的编码格式,如果是gbk,使用escape编码
* @param {Boolean=} [json=false] 发送的是否json数据
*/
post: function (url, timeout, data, callback, encoding, header, reqEncoding, json) {
var options = require('url').parse(url);
options.method = 'POST';
if (header) {
options.headers = header;
}
if (reqEncoding) {
options.encode = reqEncoding;
}
if (json) {
options.json = json;
}
this.request(options, timeout, data, callback, encoding);
}
};
/**
* @description 处理请求响应的回调方法
* @callback RequestCallback
* @param {Object} err 请求或响应的错误对象
* @param {string} data 响应的数据
* @param {Object} res 响应流对象
*/
module.exports = httpHelper;
/**
* @fileOverview tool/httpHelper单元测试
* @module test/tool/httpHelper
*/
var should = require('chai').should();
var describe = require('describe');
var httpHelper = require("./httpHelper");
//var url='http://www.yunhosting.com/index.asp';
var url='https://github.com/visionmedia/express';
/**
* @function tool/httpHelper
* @description tool/httpHelper单元测试
*/
describe('test ./httpHelper', function () {
/**
* @function get
* @description tool/httpHelper get
*/
describe('#get', function () {
it('get方式请求页面不报错', function (done) {
httpHelper.get(url, 1000, function (err, data) {
if (err) {
return done(err);
}
should.exist(data);
done();
}, 'gbk', {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'});
});
it('get方式请求Google首页超时', function (done) {
httpHelper.get('http://www.google.com/', 10, function (err, data) {
if (err && err.message === 'request timeout') {
return done();
}
done(new Error('超时时间设置无效'));
}, 'gbk');
});
});
/**
* @function post
* @description tool/httpHelper post
*/
describe('#post', function () {
it('post方式请求页面不报错', function (done) {
httpHelper.post(url, 1000, {}, function (err, data) {
if (err) {
return done(err);
}
should.exist(data);
done();
}, 'gbk', {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'});
});
it('post方式给页面发送json数据不报错', function (done) {
httpHelper.post(url, 1000, {
username: 'username',
pwd: 'pwd'
}, function (err, data) {
if (err) {
return done(err);
}
should.exist(data);
done();
}, 'gbk', undefined, 'gbk', true);
});
});
/**
* @function request
* @description tool/httpHelper request
*/
describe('#request', function () {
it('get方式请求,直接返回二进制数据', function (done) {
var options = require('url').parse(url);
options.method = 'GET';
options.buffer = true;
httpHelper.request(options, 1000, {}, function (err, data) {
if (err) {
return done(err);
}
should.exist(data);
(typeof data).should.equals('object');
done();
});
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment