HTTP协议

1.HTTP请求方法

HTTP请求方法并不是只有GET和POST,只是最常用的。据RFC2616标准(现行的HTTP/1.1)得知,通常有以下8种方法:OPTIONSGETHEAD、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请求头,用以判断实际发送的请求是否安全。

2.http的Max-Forwards头的作用

请求头的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连接断开。这提现在浏览器关闭, 服务器无法感知。

原文地址:https://www.cnblogs.com/liuyinlei/p/6288747.html