一、Nginx 代理配置和代理缓存
Nginx
是反向代理服务器。代理服务器是一个中间服务器,它主要是把英特网上的不同客户端的请求转发到不同的服务器上。而反向代理服务器则是代理服务器的一种,它也是把英特网上的不同客户端的请求转发到不同的服务器上,它这些服务器是位于某个私有网络中,且该私有网络具有防火墙(比如防火墙只允许该私有网络通过一个指定的IP
与 端口与外网连接)。- 在这一段中,
proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m;
,如下所示:
proxy_cache_path
表示表示缓存文件存放的路径,该路径是预先就要创建好的levels=1:2
表示设置在相对于path
指定目录的第几级hash
目录中缓存数据,levels=1
,表示一级hash
目录,levels=1:2
,表示两级hash
目录,目录的名称是基于请求URL
通过哈希算法得到的keys_zone=my_cache:10m
设置缓存名字
Nginx
代理配置和代理缓存的代码,如下所示:
- index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div>This is content, and data is: <span id="data"></span></div> <button id="button">click me</button> </body> <script> var index = 0 function doRequest () { var data = document.getElementById('data') data.innerText = '' fetch('/data', { headers: { 'X-Test-Cache': index++ } }).then(function (resp) { return resp.text() }).then(function (text) { data.innerText = text }) } document.getElementById('button').addEventListener('click', doRequest) </script> </html>
- server.js
const http = require('http') const fs = require('fs') const wait = (seconds) => { return new Promise((resolve) => { setTimeout(resolve, seconds * 1000) }) } http.createServer(function (request, response) { console.log('request come', request.url) if (request.url === '/') { const html = fs.readFileSync('test.html', 'utf8') response.writeHead(200, { 'Content-Type': 'text/html' }) response.end(html) } if (request.url === '/data') { response.writeHead(200, { 'Cache-Control': 'max-age=2, s-maxage=20, private', 'Vary': 'X-Test-Cache' }) wait(2).then(() => response.end('success')) } }).listen(8888) console.log('server listening on 8888')
- nginx.conf
proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m; server { listen 80; # listen [::]:80 default_server; server_name test.com; # return 302 https://$server_name$request_uri; location / { proxy_cache my_cache; proxy_pass http://127.0.0.1:8888; proxy_set_header Host $host; } } server { listen 443 http2; server_name test.com; http2_push_preload on; ssl on; ssl_certificate_key ../certs/localhost-privkey.pem; ssl_certificate ../certs/localhost-cert.pem; location / { proxy_cache my_cache; proxy_pass http://127.0.0.1:8888; proxy_set_header Host $host; } }
二、HTTPS
HTTPS协议 = HTTP协议 + SSL/TLS
协议,在HTTPS
数据传输的过程中,需要用SSL/TLS
对数据进行加密和解密,需要用HTTP
对加密后的数据进行传输,由此可以看出HTTPS
是由HTTP
和SSL/TLS
一起合作完成的。HTTPS
为了兼顾安全与效率,同时使用了对称加密和非对称加密。数据是被对称加密传输的,对称加密过程需要客户端的一个密钥,为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,总的来说,对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。HTTPS
在传输的过程中会涉及到三个密钥,服务器端的公钥和私钥,用来进行非对称加密,客户端生成的随机密钥,用来进行对称加密。- 一个
HTTPS
请求实际上包含了两次HTTP
传输,可以细分为八步,如下所示:
- 客户端向服务器发起
HTTPS
请求,连接到服务器的443
端口 - 服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人
- 服务器将自己的公钥发送给客户端
- 客户端收到服务器端的证书之后,会对证书进行检查,验证其合法性,如果发现发现证书有问题,那么
HTTPS
传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key
,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS
中的第一次HTTP
请求结束 - 客户端会发起
HTTPS
中的第二个HTTP
请求,将加密之后的客户端密钥发送给服务器 - 服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文
- 然后服务器将加密后的密文发送给客户端
- 客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样
HTTPS
中的第二个HTTP
请求结束,整个HTTPS
传输完成
HTTP2
的优势是 信道复用、分帧传输和Server Push
。
三、浏览器输入URL后HTTP请求返回的完整过程
- 在浏览器输入
URL
以后,开始时间,开始跳转,Redirect
跳转,判断结果,跳转结束。 fetch
开始,从App Cache
应用缓存中查找。- 如果没有,就从域名解析中开始,
DNS
查找,域名解析结束。 - 开始创建连接,开始创建安全链接,创建
TCP
连接,创建连接结束。 - 开始发送请求,
Request
发送请求。 - 开始接收返回,
Response
接收响应,接收接收返回。