HTTP
应用层:为应用软件提供服务,构建与TCP协议之上,屏蔽网络传输相关细节
传输层:向用户提供端到端的服务,向高层屏蔽了下层数据通信的细节
网络层 :为数据在结点之间传输创建逻辑链路
数据链路层:在通信的实体之间建立数据逻辑链路
物理层:定义物理设备如何传输数据
http:三次握手
1.客户端向服务端发送创建连接的请求,里面带有标志位,SYN=1(第一个标志位),Seq=X(数字)
2.服务端接受到客户端请求,开启tcp socket 端口,返回 SYN = 1, ACK = X+1 Seq的数字加1,Seq = Y (服务端的Seq)
3.客户端已被允许创建TCP连接,向服务端发送ACK=Y+1 ,Seq = Z
URI:统一资源标志符
用来唯一标识互联网上的信息资源
URL:统一资源定位符
URN:永久统一资源定位符
简易web服务器实现
1 const http = require('http') 2 3 http.createServer(function(req,res){ 4 console.log('req',req.url) 5 6 res.end('123') 7 }).listen(8888)
localhost:8888 123
跨域解决
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> </body> <script> var xhr = new XMLHttpRequest() xhr.open('GET','http://127.0.0.1:8887/') xhr.send() </script> </html>
server.js
1 const http = require('http') 2 const fs = require('fs') 3 4 http.createServer(function(req,res){ 5 console.log('req',req.url) 6 7 const html = fs.readFileSync('index.html','utf-8') 8 res.writeHead(200,{ 9 'Content-Type':'text/html' 10 }) 11 12 res.end(html) 13 }).listen(8888)
server2.js
const http = require('http') http.createServer(function(req,res){ console.log('req',req.url) res.writeHead(200,{ 'Access-Control-Allow-Origin':'*' }) //请求和发送正常进行,被浏览器忽略掉了 res.end('123') }).listen(8887)
CORS限制
允许方法 GET HEAD POST
允许Content-Type
text/plain
multipart/form-data
application/x-www-form-urlencoded
请求头限制
'Access-Control-Allow-Header':' '
XMLHttpRequestUpload对象均没有注册任何事件监听器
请求中没有使用ReadableStream对象
Cache-Control
可缓存性
public
private
no-cache
到期
max-age=<seconds>
s-maxage=<seconds>
max-stale=<seconds>
重新验证
must-revalidate
proxy-revalidate
Cookie
通过Set-Cookie设置
下次请求会自动带上
键值对,可以设置多个
max-age和expires设置过期时间
Secure只在https的时候发送
HttpOnly无法通过document,cookie访问
test.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 </head> 9 <body> 10 11 </body> 12 <script> 13 console.log(document.cookie) 14 </script> 15 </html>
server.js
1 const http = require('http') 2 const fs = require('fs') 3 4 http.createServer(function(req,res){ 5 console.log('req',req.url) 6 7 if(req.url === '/'){ 8 const html = fs.readFileSync('test.html','utf-8') 9 res.writeHead(200,{ 10 'Content-Type':'text/html', 11 'Set-Cookie':'123' 12 }) 13 14 res.end(html) 15 } 16 17 18 19 }).listen(8888)
Http长连接
数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据
test.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 </head> 9 <body> 10 <img src="/test.jpg" alt=""></img> 11 <img src="/test.jpg" alt=""></img> 12 <img src="/test.jpg" alt=""></img> 13 <img src="/test.jpg" alt=""></img> 14 </body> 15 <script> 16 </script> 17 </html>
server.js
const http = require('http') const fs = require('fs') http.createServer(function(req,res){ console.log('req', req.url) const html = fs.readFileSync('test.html','utf-8') const img = fs.readFileSync('test.jpg') if(req.url === '/'){ res.writeHead(200,{ 'Content-Type':'text/html' }) res.end(html) }else{ res.writeHead(200,{ 'Content-Type':'image/jpg' }) res.end(img) } }).listen(8888)
数据协商
分类
请求,返回
Accept:
Accept-Encoding
Accept-Language
User-Agent
Content-Type
Content-Type
Content-Encoding
Content-Language
redirect
1 const http = require('http') 2 const fs = require('fs') 3 4 http.createServer(function(req,res){ 5 console.log('req',req.url) 6 7 if(req.url === '/'){ 8 9 res.writeHead(302,{ 10 'Location':'/new' 11 }) 12 13 res.end('') 14 } 15 16 if(req.url === '/new'){ 17 res.writeHead(200,{ 18 'Content-Type':'<div>this is content</div>' 19 }) 20 21 res.end('<div>content</div>') 22 } 23 24 }).listen(8888)
Content-Security-Policy
CSP 内容安全策略
作用:限制资源获取
报告资源获取越权
限制方式:
default-src 限制全局
制定资源类型
test.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <div> This is content </div> 9 <script> 10 console.log('inline js') 11 </script> 12 </body> 13 </html>
server.js
const http = require('http') const fs = require('fs') http.createServer(function(req,res){ console.log('req',req.url) if(req.url === '/'){ const html = fs.readFileSync('test.html','utf-8') res.writeHead(200,{ 'Content-Type':'text/html', 'Content-Security-Policy':'default-src http: https:' }) res.end(html) } }).listen(8888)
Refused to execute inline script because it violates the following Content Security Policy
代理缓存
通过重用已获取的资源,可大幅提高web站点和应用的性能。由于web缓存减少了延迟和网络流量,因此缩短了展示一个资源所需的时间。通过使用HTTP缓存机制
test.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title></title>
6 </head>
7 <body>
8 <div> This is content:<span id="data"></span> </div>
9 <script>
10 fetch('/data').then(function(res){
11 return res.text()
12 }).then(function(text){
13 document.getElementById('data').innerText = text
14 })
15 </script>
16 </body>
17 </html>
server.js
1 const http = require('http')
2 const fs = require('fs')
3
4 const wait = (seconds) =>{ //2s后
5 return new Promise((resolve,reject) =>{
6 setTimeout(() =>{
7 resolve()
8 },seconds*1000)
9 })
10 }
11
12 http.createServer(function(req,res){
13 console.log('req',req.url)
14
15 if(req.url === '/'){
16 const html = fs.readFileSync('test.html','utf-8')
17 res.writeHead(200,{
18 'Content-Type':'text/html',
19 })
20
21 res.end(html)
22 }
23
24 if(req.url === '/data'){
25 res.writeHead(200,{
26 'Cache-Control':'max-age=20'
27 })
28 wait(2).then(()=>res.end('success'))
29
30 }
31
32
33
34 }).listen(8888)
Https
公钥
私钥
Http2
信道复用
分帧传输
Server Push
完