其他分享
首页 > 其他分享> > 升级打怪-精读图解HTTP(第五章)

升级打怪-精读图解HTTP(第五章)

作者:互联网

与HTTP协助的web服务器

单台虚拟主机实现多个域名

通过端口访问不同的主机

nginx.conf

server {
    listen       8080;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html/demo1;
        index  index.html index.php;
    }
}

server {
    listen       8081;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html/demo2;
        index  index.html index.php;
    }
}

效果:

在这里插入图片描述

通过不同域名来访问

配置两个测试域名
a.demo1.com
b.demo2.com

hosts文件

在这里插入图片描述

nginx.conf

server {
    listen       80;
    server_name  a.demo1.com;

    location / {
        root   /usr/share/nginx/html/demo1;
        index  index.html index.php;
    }
}

server {
    listen       80;
    server_name  b.demo2.com;

    location / {
        root   /usr/share/nginx/html/demo2;
        index  index.html index.php;
    }
}

效果:
在这里插入图片描述

通信数据转发程序

代理

HTTP 请求头中的 X-Forwarded-For

正向代理

定义

正向代理是指位于客户机(A)和站点服务器(B)之间的代理服务器©,为了从站点服务器(B)获取资源,客户机(A)向代理服务器©发送请求并指定站点服务器(B),然后代理服务器©向站点服务器(B)转交请求并将获取的资源返回给客户机(A),正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。

在这里插入图片描述

作用

安全性:增强内部网络安全性,使得外部网络的威胁不易影响到内部网络;
监控和管理:利用代理服务器可以对内部网络访问外部网络进行必要的监控和管理,正向代理服务器不支持外部网络对内部网络的访问请求

指令

实例
server{
	# 配置DNS解析IP地址,比如 Google Public DNS,以及超时时间(5秒)
    resolver 8.8.8.8;    # 必需
    resolver_timeout 5s;
	
	# 监听端口
    listen 80;
    location / {
		 # 配置正向代理参数
        proxy_pass $scheme://$host$request_uri;
	}
}

反向代理

定义

客户端对代理是无感知的,客户端不需要任何配置,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址
我们通过这张图来对比一下正向代理和反向代理:
在这里插入图片描述
在这里插入图片描述

总结起来还是一句话:正向代理代理客户端,反向代理代理服务器

网关

参考资料:使用 Node.js 搭建一个 API 网关

隧道

参考资料:HTTP 代理原理及实现

保存资源的缓存

http缓存请求相应头

Cache-Control

请求/响应头,缓存控制字段,可以说是控制http缓存的最高指令,要不要缓存也是它说了算.
常用值:

ps:在使用谷歌浏览器验证时,要取消Disable cache,默认是勾选的,这会导致验证失效
在这里插入图片描述

Expires

响应头,代表资源过期时间,由服务器返回提供,GMT格式日期,是http1.0属性,在于max-age共存的情况下,优先级要低

Last-Modified与If-Modified-Since

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:

	Last-Modified: Fri, 12 May 2006 18:53:33 GMT 

过程如下:
- 客户端向服务器请求资源
- 服务端返回Last-Modified(文件修改时间),并把Last-Modified值设置请求头If-Modified-Since
- 客户端再次请求时,会带着If-Modified-Since与服务端Last-Modified对比
- 不用主动获取If-Modified-Since的值,服务端自动对比,文件日期未变返回200 ok(from disk cache),从缓存拿资源,文件日期变化返回200 ok,从服务器获取最新资源

ps:客户端强制刷新(ctl+shift+R),请求会剔除Etag

node实现代码:

onst http = require("http");
const fs = require("fs");
const path = require("path");

http
  .createServer(function (req, res) {
    if (/\/(static)/.test(req.url)) {
          let content = fs.readFileSync(path.join(__dirname, req.url));
          let stat=fs.statSync(path.join(__dirname));
          console.log("access...");

          res.writeHead(200, {
            "Last-Modified": '2020-12-01T07:39:09.732Z'
          });
          console.log("access...");
          res.end(content);
    } else {
      res.setHeader("Access-Control-Allow-Origin", "*");
      let str = new Date(Date.now() + 10000).toString();
      
      res.write("hello,world");
      console.log("access...");
      res.end();
    }
  })
  .listen(8889);

效果:
第一次访问:
在这里插入图片描述
后续访问:
在这里插入图片描述

Etag与if-none-match

过程如下:
- 客户端向服务器请求资源
- 服务器返回状态值200,返回数据,并设置Etag(请求资源的指纹)
- 客户端再次请求时,根据服务端返回的Etag,设置if-none-match和Etag值一样,浏览器自动设置
- 服务端根据客户端的请求头中的if-none-match,与服务器生成的Etag值对比,相同返回304,否则返回200,并设置新的Etag

ps:客户端强制刷新(ctl+shift+R),请求会剔除Etag

node实现代码:

const http = require("http");
const fs = require("fs");
const path = require("path");

http
  .createServer(function (req, res) {
    if (/\/(static)/.test(req.url)) {
        var hashStr = "A hash string.";
        var hash = require("crypto").createHash("sha1").update(hashStr).digest("base64");
    try {
        const etag = req.headers["if-none-match"];
        console.log(etag);

        if (etag === hash) {
          res.writeHead(304);
          res.end();
        } else {
          res.writeHead(200, {
            Etag: hash,
          });

          let content = fs.readFileSync(path.join(__dirname, req.url));
          console.log("access...");

          res.end(content);
        }
      } catch (error) {
        console.log(error);
      }
    } else {
      res.setHeader("Access-Control-Allow-Origin", "*");
      res.write("hello,world");
      res.end();
    }
    })
  .listen(8889);

效果:
第一次访问:
在这里插入图片描述
后续访问:
在这里插入图片描述

使用HTTP缓存原因

http缓存使用方案发展历程

1.让服务器与浏览器约定一个文件过期时间——Expires(GMT时间格式)

流程:
问题:

2.让服务器与浏览器在约定文件过期时间的基础上,再加一个文件最新修改时间的对比——Last-Modified与if-Modified-Since

流程
问题

3.让服务器与浏览器在过期时间Expires+Last-Modified的基础上,再增加一个文件内容唯一对比标记——Etag与If-None-Match。哦对了,我们说Expires不稳定,这里我们再加入一个max-age来加以代替(cache-control其中一个值)。

流程
问题

4.http缓存方案

md5/hash缓存

通过不缓存html,为静态文件添加MD5或者hash标识,解决浏览器无法跳过缓存过期时间主动感知文件变化的问题。

原理

我们前面说的http缓存方案,服务器与浏览器的文件修改时间对比,文件内容标识对比,前提基础都是建立在两者文件路径完全相同的情况下。
module/js/a-hash1.js与module/js/a-hash2.js是两个完全不同的文件,假想浏览器第一次加载页面,请求并缓存了module/js/a-hash1.js,第二次加载,文件指向变成了module/js/a-hash2.js,浏览器会直接重新请求a-hash2.js,因为这就是两个完全不同的文件,哪里还有什么http缓存文件对比,t通过这种做法,我们就可以从根本上解决过期时间没到浏览器无法主动请求服务器的问题。因此我们只需要在项目每次发布迭代将修改过的静态文件添加不同的MD5或hash标识就好啦。
注意,这里不推荐缓存html文件(或许有更好的做法,欢迎留言),这样每次html加载渲染都可以感知文件变化,反正文件没变还是使用本地缓存,文件名都变了说明修改过,重新请求缓存就好了。

CDN缓存(作为了解)

CDN定义:
CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。

CDN缓存定义:
CDN边缘节点缓存数据,当浏览器请求,CDN将代替源站判断并处理此处请求。

问题:
CDN缓存的问题也跟前面的http缓存一样,CDN缓存时间不过期,浏览器始终被拦截,无法拿到最新的文件。

解决方案:
CDN类似一个平台,是可以通过登录,手动更新CDN缓存的,变相解决了浏览器缓存无法手动控制的问题

浏览器地址栏回车,新开窗口,F5刷新,CTRL+F5刷新等浏览器操作对HTTP缓存的影响

在这里插入图片描述

强缓存与协商性缓存(弱缓存)

强缓存

不发起http请求,直接使用本地缓存,比如浏览器地址栏回车,使用浏览器的刷新按钮,在Expires或max-age生效的情况下,触发的都是强缓存。

协商性缓存(弱缓存)

在使用本地缓存前,先与服务器协商,核对缓存文件是否为最新。比如设置了cache-control=no-cache,不管你做任何操作,都会发起请求,这一类就是协商性缓存了。

max-age和Expires的区别

参考资料:http缓存详解,http缓存推荐方案

标签:文件,精读,HTTP,请求,Modified,打怪,缓存,服务器,浏览器
来源: https://blog.csdn.net/ken_ding/article/details/110183874