express之request.js
发布日期:2021-05-28 16:23:58
浏览次数:30
分类:技术文章
本文共 6160 字,大约阅读时间需要 20 分钟。
lib/request.js//请求原型对象继承了http原生的请求原型var req = Object.create(http.IncomingMessage.prototype)module.exports = req//get、header方法都是获取指定名称请求头req.get =req.header = function header(name) { //名称不存在,抛出错误 if (!name) { throw new TypeError('name argument is required to req.get'); } //名称不是字符串,抛出错误 if (typeof name !== 'string') { throw new TypeError('name must be a string to req.get'); } //名称转化为小写,内部都是以小写来存储的 var lc = name.toLowerCase(); //特殊处理referer、referrer switch (lc) { case 'referer': case 'referrer': return this.headers.referrer || this.headers.referer; default: //默认返回headers中属性值,这个headers是IncomingMessage上的属性 return this.headers[lc]; }};//检查指定MIME类型是否可以接受//参数可以为application/json等标准MIME类型,也可以是json、html等扩展名//如果指定类型可以接收,返回它,如果不可接受,返回undefined//如果为类型数组,返回最佳匹配//但是在哪设置可以接受的MIME类型?req的属性上吗req.accepts = function(){ var accept = accepts(this); return accept.types.apply(accept, arguments);};//给定请求编码是否可接受req.acceptsEncodings = function(){ var accept = accepts(this); return accept.encodings.apply(accept, arguments);};//不带s的函数已经废弃req.acceptsEncoding = deprecate.function(req.acceptsEncodings, 'req.acceptsEncoding: Use acceptsEncodings instead');//指定字符集是否可接受req.acceptsCharsets = function(){ var accept = accepts(this); return accept.charsets.apply(accept, arguments);};req.acceptsCharset = deprecate.function(req.acceptsCharsets, 'req.acceptsCharset: Use acceptsCharsets instead');//指定语言是否可接受req.acceptsLanguages = function(){ var accept = accepts(this); return accept.languages.apply(accept, arguments);};req.acceptsLanguage = deprecate.function(req.acceptsLanguages, 'req.acceptsLanguage: Use acceptsLanguages instead');//获取请求头中Range字段,解析后返回//Range字段用来设置要下载资源的字节返范围req.range = function range(size, options) { //获取Range请求头 var range = this.get('Range'); //不存在返回undefined if (!range) return; //解析字段,返回一个对象数组,对象有start、end属性指明要下载的字节位置 return parseRange(size, range, options);};/** * Return the value of param `name` when present or `defaultValue`. * * - Checks route placeholders, ex: _/user/:id_ * - Checks body params, ex: id=12, {"id":12} * - Checks query string params, ex: ?id=12 * * To utilize request bodies, `req.body` * should be an object. This can be done by using * the `bodyParser()` middleware. * * @param {String} name * @param {Mixed} [defaultValue] * @return {String} * @public *///获取指定名称参数,没有返回默认值//获取参数顺序为:路由占位符如:id形式、请求体参数、查询字符串参数req.param = function param(name, defaultValue) { //分别获取路由占位符参数对象、请求体参数对象、查询字符串参数对象 var params = this.params || {}; var body = this.body || {}; var query = this.query || {}; //已废弃 var args = arguments.length === 1 ? 'name' : 'name, default'; deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); //依次查找返回 if (null != params[name] && params.hasOwnProperty(name)) return params[name]; if (null != body[name]) return body[name]; if (null != query[name]) return query[name]; return defaultValue;};//根据content-type请求头检查请求是否是指定MIME类型req.is = function is(types) { var arr = types; //转化为参数数组 if (!Array.isArray(types)) { arr = new Array(arguments.length); for (var i = 0; i < arr.length; i++) { arr[i] = arguments[i]; } } //使用库来检查 return typeis(this, arr);};//protocol的getter函数defineGetter(req, 'protocol', function protocol(){ //socket连接如果是加密的为https,否则为http var proto = this.connection.encrypted ? 'https' : 'http'; var trust = this.app.get('trust proxy fn'); //信任代理函数 if (!trust(this.connection.remoteAddress, 0)) { return proto; } //从x-forwarded-proto请求头获取协议,当一个请求最初发出时的协议,由反向代理设置 var header = this.get('X-Forwarded-Proto') || proto var index = header.indexOf(',') return index !== -1 ? header.substring(0, index).trim() : header.trim()});//如果是https协议,返回truedefineGetter(req, 'secure', function secure(){ return this.protocol === 'https';});//远程ipdefineGetter(req, 'ip', function ip(){ var trust = this.app.get('trust proxy fn'); return proxyaddr(this, trust);});//所有ip,包含了代理服务器ipdefineGetter(req, 'ips', function ips() { var trust = this.app.get('trust proxy fn'); var addrs = proxyaddr.all(this, trust); addrs.reverse().pop() return addrs});//子域名数组defineGetter(req, 'subdomains', function subdomains() { //域名 var hostname = this.hostname; if (!hostname) return []; //子域名偏移 var offset = this.app.get('subdomain offset'); var subdomains = !isIP(hostname) ? hostname.split('.').reverse() : [hostname]; return subdomains.slice(offset);});//url解析后的pathname,代表了端口号后面查询?前面的部分defineGetter(req, 'path', function path() { return parse(this).pathname;});//域名defineGetter(req, 'hostname', function hostname(){ //信任代理函数 var trust = this.app.get('trust proxy fn'); //代理域名 var host = this.get('X-Forwarded-Host'); //域名不存在 if (!host || !trust(this.connection.remoteAddress, 0)) { //返回请求头中域名 host = this.get('Host'); } if (!host) return; // IPv6 literal support var offset = host[0] === '[' ? host.indexOf(']') + 1 : 0; var index = host.indexOf(':', offset); //获取端口号之前的域名 return index !== -1 ? host.substring(0, index) : host;});//已废弃defineGetter(req, 'host', deprecate.function(function host(){ return this.hostname;}, 'req.host: Use req.hostname instead'));//请求是否的响应是否新鲜的defineGetter(req, 'fresh', function(){ //请求方法 var method = this.method; //响应 var res = this.res //状态码 var status = res.statusCode //get、head方法不进行验证,因为他们是幂等的 if ('GET' !== method && 'HEAD' !== method) return false; //状态码在200到300之间,或者304 if ((status >= 200 && status < 300) || 304 === status) { //调用库来验证 return fresh(this.headers, { 'etag': res.get('ETag'), 'last-modified': res.get('Last-Modified') }) } //其他的状态码都不是新鲜的 return false;});//请求是否是陈旧的defineGetter(req, 'stale', function stale(){ return !this.fresh;});//请求是否是ajax请求defineGetter(req, 'xhr', function xhr(){ //获取头信息来判断 var val = this.get('X-Requested-With') || ''; return val.toLowerCase() === 'xmlhttprequest';});//帮助函数,创建getter函数function defineGetter(obj, name, getter) { Object.defineProperty(obj, name, { configurable: true, enumerable: true, get: getter });}
这个原型对象继承了node原生的IncomingMessage,在express方法中创建,并且作为app.request属性,最后在init中间件中被req参数继承
转载地址:https://blog.csdn.net/qq_27868061/article/details/79250143 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年11月21日 01时05分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
光伏机器人最前线_华师大研发种树机器人 种植效率提高100倍以上
2019-06-17
jeecgboot 前端环境搭建_Jenkins +nginx 搭建前端构建环境
2019-06-17
跑带宽度多少合适_家用跑步机尺寸一般是多少
2019-06-17
zookeeper 进入客户端_Zookeeper客户端使用与集群原理
2019-06-17
回归标准差和残差平方和的关系_毕业论文中,回归分析中15个统计量解释
2019-06-17
异步任务_Spring Boot如何高效实现异步任务
2019-06-17
怎么跳转到源代码_程序员怎么快速接手一个项目
2019-06-17
战队不显示名字了_《新天龙八部》巅峰预选赛13大阵容分析有你心仪的战队吗?...
2019-06-17
jsp 上传转码_最完整的处理jsp处理乱码问题步骤,不需要手工转码
2019-06-17
python统计函数库_python统计函数库scipy.stats的用法1/3
2019-06-17
php 复制文件夹并压缩到最小_php 压缩文件夹
2019-06-17
fifo页面置换算法设计思路_说说限流算法与设计思路
2019-06-17
lr检查磁盘时出错_win7系统提示数据错误循环冗余检查如何解决【教程】
2019-06-17
mysql 执行错误1395_主义 - 常规错误:1395无法删除连接视图
2019-06-17
如何安装mysql5.6实例_安装mysql5.6和多实例配置
2019-06-17
.frm mysql_mysqlfrm使用
2019-06-17
mysql数据库增加一行_在数据库中添加一行的SQL语句怎么写?
2019-06-17
mysql 获取备注_java 如何获取 mysql 备注信息
2019-06-17