thinkjs框架中如何判断一个请求是否为https协议请求首先我们需要明白一点,在think-js中官方文档2.2-http模块,官方说明http.req和http.res是系统原始的请求和响应对象!从整个api文档来看,http模块并没有实现类似express的req.protocol和req.secure。所以我们无法直接从请求中获取请求是http还是https。该怎么办?要了解如何获取协议类型,我们需要先了解一些内容。什么是https?HTTPS(也称为HTTPoverTLS、HTTPoverSSL和HTTPSecure])是一种在Internet上广泛使用的计算机网络安全通信协议。简而言之,https是建立在安全套接字层(ssl)或传输层安全(tls)之上的一种安全通信协议,在Internet上广泛使用。但目前我们真正广泛使用的是TLS协议。如果使用了TLS,我们应该如何判断在使用TLS时,net.Socket会收到一个值为22字节的header数据,这说明在握手协议时使用了TLSvarnet=require('net');变种基地地址=3000;net.createServer(tcpConnection).listen(baseAddress);functiontcpConnection(conn){conn.once('data',function(buf){varaddress=(buf[0]===22)?console.log('https'):console.log('http');});});}显然这并不适合我们,因为我们目前需要的是从控制设备中获取协议类型。另一种判断方式如果我们愿意去浏览koa或者express的源码,我们可以很容易的获得我们想要的知识。下面是express对protocol的处理/***当用TLS请求时,返回协议字符串"http"or"https"*。当“信任代理”*设置信任套接字地址时,*“X-Forwarded-Proto”标头字段将被信任*并在存在时使用。**如果您在反向代理后面运行*为您提供https,这可能会被启用。**@return{String}*@public*/defineGetter(req,'protocol',functionprotocol(){varproto=this.connection.encrypted?'https':'http';vartrust=this.app.get('trustproxyfn');if(!trust(this.connection.remoteAddress,0)){returnproto;}//注意:X-Forwarded-Proto通常只有一个//单一值,但这是为了besafe.proto=this.get('X-Forwarded-Proto')||proto;returnproto.split(/\s*,\s*/)[0];});/***简写对于:**req.protocol==='https'**@return{Boolean}*@public*/defineGetter(req,'secure',functionsecure(){returnthis.protocol==='https';});从代码中我们可以看出,node在使用TLS时,会在原始连接对象上携带加密信息。如果不是TLS,则此请求.connection.encrypted将是未定义的。如果express设置了可信代理,它会先检查可信代理的地址是否与远程地址匹配,或者header中包含'X-Forwarded-Proto'(可能是来自Nginx或其他代理添加的协议指示)也会返回相应的协议类型。在thinkjs中,没有expressapp.set('trustproxy')这样的方法,所以我们可以直接在controller里面写//controllerxxx.js'usestrict';importBasefrom'./base.js';functiongetProtocol(http){让proto=http.req.connection.encrypted?'https':'http';proto=http.header('X-Forwarded-Proto')||原型;returnproto.split(/\s*,\s*/)[0];}exportdefaultclassextendsBase{/***索引操作*@return{Promise}[]*/*indexAction(){console.log('protocol:',getProtocol(this.http))}}稍微集成协议功能。
