关于http的npm包
1.proxy_addr
确定代理服务器的地址
function compile(val) { //必须要有参数 if (!val) { throw new TypeError('argument is required'); } var trust = typeof val === 'string' ? [val] : val; if (!Array.isArray(trust)) { throw new TypeError('unsupported trust argument'); } for (var i = 0; i < trust.length; i++) { //trust中可以是:linklocal(DHCP服务器自动分配地址出错,本地自动分配地址)
//保留地址 loopback(本机): //内部循环 uniquelocal //本地局域网,这三种ip地址不能做代理服务器,需要剔除掉 val = trust[i]; //如果数组对象不是ipranges中那么不进行任何处理。 if (!ipranges.hasOwnProperty(val)) { continue; } // Splice in pre-defined range val = ipranges[val]; //把trust[i]删除.同时插入val数组,第一个参数是i,第二个参数是1个,第三个参数是val数组 trust.splice.apply(trust, [i, 1].concat(val)); //trust数组长度增加,i直接跳到还没有处理的下标。 i += val.length - 1; } return compileTrust(compileRangeSubnets(trust)); }
2.mime-types
最终的JavaScript内容类型实用程序,提供API有charset、contentType、extension和lookup。看看lookup源码:
function lookup (path) { if (!path || typeof path !== 'string') { return false } // get the extension ("ext" or ".ext" or full path) var extension = extname('x.' + path) .toLowerCase() .substr(1) if (!extension) { return false } //获取以path为扩展名的mime-type return exports.types[extension] || false }
客户端向后台上传文件或者提交表单是content-type头会有:multipart/form-data、application/octet-stream、和application/x-www-form-urlencoded。这三者区别是:
http://blog.csdn.net/wangjun5159/article/details/49644507
3.Accepts
提供两个成员变量:
//构造函数参数为req function Accepts(req) { if (!(this instanceof Accepts)) return new Accepts(req) this.headers = req.headers this.negotiator = new Negotiator(req) }
和四个方法:
Accepts.prototype.types
Accepts.prototype.encodings
Accepts.prototype.charsets
Accepts.prototype.languages
他们的功能和写法都差不多,解析一个:
var types = ["html","text","json","jpg"]; var mimes = types.map(extToMime); //[ 'text/html', 'application/json', 'text/plain' ] console.log(mimes); var req = { headers:{ Accept:"application/json, text/javascript, */*; q=0.01" } } var nego = new Negotiator(req); var accepts = nego.mediaTypes(mimes.filter(validMime)); //[ 'text/html', 'application/json', 'text/plain', 'image/jpeg' ] console.log(accepts); var first = accepts[0]; //res=html var res = types[mimes.indexOf(first)]; console.log("res="+res);
4. fresh
使用请求和响应的头部来判断响应的新鲜度,如果返回true,表示客户端的缓存仍然是有效的,为false,,表示客户端的缓存失效,请求应发送完整的响应。
5.etag
给http响应头打上etag标签
6.statuses
获取http的状态码的详细信息。
// [Integer...] status.codes = { ... } // status codes for redirects status.redirect = { .... }; // status codes for empty bodies status.empty = { ... }; // status codes for when you should retry the request status.retry = { ... }; function status(code) { //code可以是数字和字符串,如果是数字,返回是msg,字符串,返回code。 //如果没有匹配到,则抛出错误。 return n; }
7.on-finished
当一个请求执行完毕,关闭,或者出错,执行回调函数。
8.http-error
function toIdentifier(str) { return str.split(' ').map(function (token) { return token.slice(0, 1).toUpperCase() + token.slice(1) }).join('').replace(/[^ _0-9a-z]/gi, '') } console.log(toIdentifier("Pa&rtial Content")); //PartialContent
看具体代码:
var statuses = require('statuses'); var inherits = require('inherits'); function toIdentifier(str) { return str.split(' ').map(function (token) { return token.slice(0, 1).toUpperCase() + token.slice(1) }).join('').replace(/[^ _0-9a-z]/gi, '') } exports = module.exports = function httpError() { // so much arity going on ~_~ var err; var msg; var status = 500; var props = {}; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (arg instanceof Error) { err = arg; status = err.status || err.statusCode || status; continue; } switch (typeof arg) { case 'string': msg = arg; break; case 'number': status = arg; break; case 'object': props = arg; break; } } if (typeof status !== 'number' || !statuses[status]) { status = 500 } // constructor var HttpError = exports[status] if (!err) { // create error err = HttpError ? new HttpError(msg) : new Error(msg || statuses[status]) Error.captureStackTrace(err, httpError) } if (!HttpError || !(err instanceof HttpError)) { // add properties to generic error err.expose = status < 500 err.status = err.statusCode = status } for (var key in props) { if (key !== 'status' && key !== 'statusCode') { err[key] = props[key] } } //返回Error的实例,这个实例需要有expose,status、expose值。 return err; }; // create generic error objects var codes = statuses.codes.filter(function (num) { return num >= 400; }); //exports有两个成语属性:code和name。属性值为自定义的Error。 codes.forEach(function (code) { var name = toIdentifier(statuses[code]) var className = name.match(/Error$/) ? name : name + 'Error' if (code >= 500) { //ServerError是自定义Error。 var ServerError = function ServerError(msg) { var self = new Error(msg != null ? msg : statuses[code]) Error.captureStackTrace(self, ServerError) self.__proto__ = ServerError.prototype Object.defineProperty(self, 'name', { enumerable: false, configurable: true, value: className, writable: true }) return self } inherits(ServerError, Error); ServerError.prototype.status = ServerError.prototype.statusCode = code; ServerError.prototype.expose = false; //每个大于500的状态码和对应的状态信息都有ServerError,ServerError继承error,同时原型有 //status和statusCode、expose信息。 exports[code] = exports[name] = ServerError return; } var ClientError = function ClientError(msg) { var self = new Error(msg != null ? msg : statuses[code]) Error.captureStackTrace(self, ClientError) self.__proto__ = ClientError.prototype Object.defineProperty(self, 'name', { enumerable: false, configurable: true, value: className, writable: true }) return self } inherits(ClientError, Error); ClientError.prototype.status = ClientError.prototype.statusCode = code; ClientError.prototype.expose = true; exports[code] = exports[name] = ClientError return; }); // backwards-compatibility exports["I'mateapot"] = exports.ImATeapot
9.vary
/*过滤fields数组中的值,如果vals数组没有fields数组中的值。会把该值push到vals数组中,同时修改val,如果val值没有,赋值fields[i]。*/ for (var i = 0; i < fields.length; i++) { var fld = fields[i].toLowerCase(); // append value (case-preserving) if (vals.indexOf(fld) === -1) { vals.push(fld); val = val ? val + ', ' + fields[i] : fields[i]; } }
10.uid-safe
var uid = require('uid-safe').sync var generateId = opts.genid || generateSessionId //生成session_id function generateSessionId(sess) { return uid(24); }
11.cookie-signature
对cookie进行加密解密,先看例子:
var cookie=require('./index'); var val = cookie.sign('hello', 'tobiiscool'); console.log(val); //打印hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI var unsign2=cookie.unsign(val, 'tobiiscoolx'); console.log("unsign2 = ",unsign2); //打印unsign2 = false var unsign=cookie.unsign(val, 'tobiiscool') console.log(unsign); //打印hello
与对cookie处理的包还有cookie,cookie-parse,这都比较简单。