HTTP协议
1.HTTP请求方法
HTTP请求方法并不是只有GET和POST,只是最常用的。据RFC2616标准(现行的HTTP/1.1)得知,通常有以下8种方法:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT。
官方定义
HEAD方法跟GET方法相同,只不过服务器响应时不会返回消息体。一个HEAD请求的响应中,HTTP头中包含的元信息应该和一个GET请求的响应消息相同。这种方法可以用来获取请求中隐含的元信息,而不用传输实体本身。也经常用来测试超链接的有效性、可用性和最近的修改。
一个HEAD请求的响应可被缓存,也就是说,响应中的信息可能用来更新之前缓存的实体。如果当前实体跟缓存实体的阈值不同(可通过Content-Length、Content-MD5、ETag或Last-Modified的变化来表明),那么这个缓存就被视为过期了。
HEAD请求常常被忽略,但是能提供很多有用的信息,特别是在有限的速度和带宽下。主要有以下特点:
1、只请求资源的首部;
2、检查超链接的有效性;
3、检查网页是否被修改;
4、多用于自动搜索机器人获取网页的标志信息,获取rss种子信息,或者传递安全认证信息等
OPTIONS请求方法的主要用途有两个:
1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。
2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
请求头的Max-Forwards用来请求特定代理。当代理收到一个允许URI转发的OPTIONS请求,则检查Max-Forwards。如果Max-Forwards值为0,则不能转发该消息;
相反,代理会将自己的通信选项去响应。如果Max-Forwards是正整数,代理转发请求的时候会将该值减1。如果请求中没有Max-Forwards,转发的请求也不会有。
与之对应的字段还有X-Forwarded-Proto:记录一个请求浏览器发出到目前主机使用什么协议来传输,下面是一段node程序来判断是否请求为安全:
function issecure(req, trustProxy) { // socket is https server if (req.connection && req.connection.encrypted) { return true; } // do not trust proxy if (trustProxy === false) { return false; } // no explicit trust; try req.secure from express if (trustProxy !== true) { var secure = req.secure; return typeof secure === 'boolean' ? secure : false; } // read the proto from x-forwarded-proto header var header = req.headers['x-forwarded-proto'] || ''; var index = header.indexOf(','); var proto = index !== -1 ? header.substr(0, index).toLowerCase().trim() : header.toLowerCase().trim() return proto === 'https'; }
x-forwarded-for:
只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。格式为:X-Forwarded-For: client1, proxy1, proxy2。最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。 在上面这个例子中,这个请求成功通过了三台代理服务器:proxy1, proxy2。
获取代码的IP地址:npm forwards源码:
function forwarded(req) { if (!req) { throw new TypeError('argument req is required') } // simple header parsing var proxyAddrs = (req.headers['x-forwarded-for'] || '') .split(/ *, */) .filter(Boolean) .reverse() //req.connection返回的net包中的socket对象,远程IP地址的字符串表示。 var socketAddr = req.connection.remoteAddress //如果没有代理;客户端IP地址从 req.connection.remoteAddress 得来,这是默认的设置。 var addrs = [socketAddr].concat(proxyAddrs) // return all addresses [proxy2.proxy1,client] return addrs }
3.请求添加HTTP首部
XHR对象API允许应用添加自定义的HTTP首部(通过setRequestHeader()方法),同时也有一些首部都是应用代码不能设定的。
Accept-Charset、Accept-Encoding、Access-Control-*
Host、Upgrade、Connection、Refer、Origin
Cookie、Set-*、Proxy-*
4.Access-Control-Allow-Headers
以Access-Control-开头的字段,有三个与CORS请求相关的字段,CORS请求具体查看:http://www.ruanyifeng.com/blog/2016/04/cors.html
5.Range:在HTTP头中,"Range"字眼都表示“资源的byte形式数据的顺序排列,并且取其某一段数据”的意思。Range头就是表示请求资源的从某个数值到某个数值间的数据,例如:Range: bytes=500-999 就是表示请求资源从500到999byte的数据。数据的分段下载和多线程下载就是利用这个实现的。与Range有关系的字段是IF-Range,它属于附带条件之一,如果请求的资源的Etag值或时间相一致时,则作为范围请求处理。反正,则返回全体资源。
6.MIME-type
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据;媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的,例如:text/HTML。
7.if-none-match和etag
if-none-match是请求头中的数据,etag是响应头中的数据。下面是工作原理
类似这样的还有If-Modified-Since和Last-Modified。理解了这之后,就很容易理解npm包fresh的源码了:
function fresh(req, res) { // defaults var etagMatches = true; var notModified = true; // fields var modifiedSince = req['if-modified-since']; var noneMatch = req['if-none-match']; var lastModified = res['last-modified']; var etag = res['etag']; var cc = req['cache-control']; // unconditional request if (!modifiedSince && !noneMatch) return false; // check for no-cache cache request directive if (cc && cc.indexOf('no-cache') !== -1) return false; // parse if-none-match if (noneMatch) noneMatch = noneMatch.split(/ *, */); // if-none-match if (noneMatch) { etagMatches = noneMatch.some(function (match) { return match === '*' || match === etag || match === 'W/' + etag; }); } // if-modified-since if (modifiedSince) { modifiedSince = new Date(modifiedSince); lastModified = new Date(lastModified); notModified = lastModified <= modifiedSince; } //etagMatches和notModified有一个为false,则表示客户端需要重新发起请求。 return !! (etagMatches && notModified); }
参考博客:http://blog.csdn.net/liangklfang/article/details/51043091
8.accept和content-type
参考博客:http://blog.csdn.net/muzizongheng/article/details/46795243
content-Location : 报文主体部分相对应的URI,也就是说,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI。
9.基本认证和摘要认证
参考博客:http://blog.csdn.net/a464057216/article/details/52705855
10.什么是base64
参考博客:https://segmentfault.com/a/1190000004533485?_ea=657625
11.204、504响应码
参考博客:http://www.netingcn.com/http-status-204.html
504 Gateway Time-out是一个常见的网页错误,字面意思我们可以理解为网页请求超时,也是浏览网站网页所发出的请求没有反应或者未响应
12.X-Content-Type-Options
有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。
如果定义了X-Content-Type-Options: nosniff,那么可以禁用浏览器的类型猜测行为。该字段固定值为nosniff,一般用于jsonp的响应字段。
13.Content-Disposition
文件下载需要设置的响应头:
参考博客:http://www.cnblogs.com/brucejia/archive/2012/12/24/2831060.html
14.vary
用户代理服务器对缓存的一种储存策略。
15. Content-Location
和vary一样,主要的使用场景是用来表明作为内容协商结果响应的资源的URL。
它又和Location是不同的:Location表明重定向的目标(302),而Content-Location表明无需进行进一步的内容协商就可以直接访问的资源的URL,例如英文环境客户端发送 url_file_a 可以得到文件fileA,那么假设响应中Content-Location中内容为 url_file_a_en ,则这个url可以直接访问到对应的那个英文文件,此时其实就不存在内容协商了。 Location是一个与响应相关的头信息,而Content-Location是与返回的内容主体相关的头信息。
16.rejectUnauthorized
当请求https时,如果访问不了是由于没有认证证书,可以设置rejectUnauthorized: false, 请求时不需要认证证书
17. http连接是无状态的,所以后端无法监听http连接断开。这提现在浏览器关闭, 服务器无法感知。