java面试

HTTP 详解

2019-03-01  本文已影响161人  AKyS佐毅

1、经典五层模型

传输层: 向用户提供可靠的端到端服务。传输层向高层屏蔽了下层数据通信的细节

应用层: 为应用软件提供服务,构建于TCP协议之上屏蔽了网络传输相关细节

image

2、HTTP的三次握手

image image image image.png image.png image.png

3、抓包工具分析

image

4、HTTP报文格式

image image

GET和POST方式的区别 标准答案:

HTTP的特点:

1)无连接
经过了建立连接和释放连接的过程。可以通过HTTP的持久连接方案来进行无连接的补偿。
2)无状态
对于同一个用户,多次进行http请求时,server是不知道是否是同一个用户。可以通过cookie/session来解决。

非持久连接的定义:

每次进行http请求都是重新创建一个连接,经历三次握手和四次挥手。
持久连接的定义:
打开一条tcp通道,多个http请求在同一条tcp通道上进行,在一段time后关闭。

持久连接:
头部字段:
connection:keep-alive,表示客户端期许采用持久连接。
time:20,持久连接持续多久有效。
max:10,这条连接最多发生多少个http请求。

持久连接中,怎样判断一个请求是否结束?

1)通过响应中的content-length字段的值来判断。
2)chunked,比如通过post请求server端给客户端可能会多次响应返回数据,当有多个块通过http的tcp连接传给客户端时,每一个报文都会带有chunked字段,而最后一个块是一个空的chunked。所以可以通过判断哪个chunked是空的来判断前一个网络请求是否结束。

charles抓包原理是怎样的?

利用了http的中间人攻击这个漏洞。
中间人攻击的定义:
当client发送一个http请求时,是由中间人进行hold住,然后中间人假冒client的身份向server端进行同样的请求,然后server端返回结果给中间人,再由中间人返给client。
如果使用http进行请求或者响应时,中间人可以篡改我们发起的请求参数,server端发回的数据也可以被篡改之后再发给client。

6、状态码的含义:

7、跨域问题实战

创建server.js

const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const html = fs.readFileSync('test.html', 'utf8')
  response.writeHead(200, {
    'Content-Type': 'text/html'
  })
  response.end(html)
}).listen(8888)

console.log('server listening on 8888')
<!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>

创建server2.js

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  // response.writeHead(200, {
  //   'Access-Control-Allow-Origin': 'http://127.0.0.1:8888',
  //   'Access-Control-Allow-Headers': 'X-Test-Cors',
  //   'Access-Control-Allow-Methods': 'POST, PUT, DELETE',
  //   'Access-Control-Max-Age': '1000'
  // })
  response.end('123')
}).listen(8887)

console.log('server listening on 8887')

启动之后,访问8888端口,出现如下错误

image
Access to XMLHttpRequest at 'http://127.0.0.1:8887/' from origin 'http://localhost:8888' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

是因为跨域的问题,无法访问,那么需要设置访问权限

[图片上传失败...(image-d8a46e-1551450048215)]

同时我们可以根据url中不同的host判断,允许一些网址可以跨域访问。

8、CORS跨域限制以及预请求验证

image

9、缓存头Cache-Control的含义和使用

<!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 src="/script.js"></script>
</html>
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 === '/script.js') {
    response.writeHead(200, {
      'Content-Type': 'text/javascript',
      'Cache-Control': 'max-age=20'
    })
    response.end('console.log("script loaded")')
  }
}).listen(8888)

console.log('server listening on 8888')
image

所以一半的资源改变最好添加版本号,否则可以打包后可以没有刷新缓存。

10、缓存验证Last-Modified和Etag的使用

image image
const http = require('http')
const fs = require('fs')

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 === '/script.js') {
    
    const etag = request.headers['if-none-match']
    if (etag === '777') {
      response.writeHead(304, {
        'Content-Type': 'text/javascript',
        'Cache-Control': 'max-age=2000000, no-cache',
        'Last-Modified': '123',
        'Etag': '777'
      })
      response.end()
    } else {
      response.writeHead(200, {
        'Content-Type': 'text/javascript',
        'Cache-Control': 'max-age=2000000, no-cache',
        'Last-Modified': '123',
        'Etag': '777'
      })
      response.end('console.log("script loaded twice")')
    }
  }
}).listen(8888)

console.log('server listening on 8888')

11、cookie和session

12、重定向

const http = require('http')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  if (request.url === '/') {
    response.writeHead(302, {  // or 301
      'Location': '/new'
    })
    response.end()
  }
  if (request.url === '/new') {
    response.writeHead(200, {
      'Content-Type': 'text/html',
    })
    response.end('<div>this is content</div>')
  }
}).listen(8888)

console.log('server listening on 8888')

13、CSP Content-Security-Policy

const http = require('http')
const fs = require('fs')

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',
      // 'Content-Security-Policy': 'script-src \'self\'; form-action \'self\'; report-uri /report'
    })
    response.end(html)
  } else {
    response.writeHead(200, {
      'Content-Type': 'application/javascript'
    })
    response.end('console.log("loaded script")')
  }
}).listen(8888)

console.log('server listening on 8888')
<!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">
  <meta http-equiv="Content-Security-Policy" content="script-src 'self'; form-action 'self';">
  <title>Document</title>
</head>
<body>
  <div>This is content</div>
  <script>
    console.log('inline js')
  </script>
  <script src="test.js"></script>
  <script src="https://cdn.bootcss.com/jquery/3.3.1/core.js"></script>
</body>
</html>

限制资源的加载,限制提交的范围

具体请参考: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

image

14、传输层协议

image

1、UDP,用户数据报协议:

特点:
1)无连接 不用在数据传输之前进行连接和释放连接。
2)尽最大努力交付
3)面向报文 既不合并,也不拆分。

报文可大可小,既不合并,也不拆分。
应用层报文会原封不动作为传输层UDP数据报的数据部分和UDP首部组成运输层的UDP数据报。

image image image

2、TCP的面向连接:

image

确认迟到:

image

确认丢失:

image

超时重传情况:

image

无差错情况:

image

3、TCP面向字节流的概念:

image

15、HTTPS建立流程

image

HTTPS建立流程描述1:

HTTPS建立流程描述2:

HTTPS建立流程描述3:

从 CA 证书讲起了。CA 证书其实就是数字证书,是由 CA 机构颁发的。至于 CA 机构的权威性,那么是毋庸置疑的,所有人都是信任它的。CA 证书内一般会包含以下内容:

PKI体系

另外,服务器也可以对自己的发出的信息进行否认,不承认相关信息是自己发出。
因此该方案下至少存在两类问题:中间人攻击和信息抵赖。

image image

在这个过程注意几点:

正好我们把客户端如何校验 CA 证书的步骤说下吧。

CA 证书中的 Hash 值,其实是用证书的私钥进行加密后的值(证书的私钥不在 CA 证书中)。然后客户端得到证书后,利用证书中的公钥去解密该 Hash 值,得到 Hash-a ;然后再利用证书内的签名 Hash 算法去生成一个 Hash-b 。最后比较 Hash-a 和 Hash-b 这两个的值。如果相等,那么证明了该证书是对的,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,可能被篡改了,浏览器会给出相关提示,无法建立起 HTTPS 连接。除此之外,还会校验 CA 证书的有效时间和域名匹配等。

接下来我们就来详细讲一下 HTTPS 中的 SSL 握手建立过程,假设现在有客户端 A 和服务器 B :

到此,SSL 握手过程就讲完了。可能上面的流程太过于复杂,我们简单地来讲:

我们可以发现,在 HTTPS 加密原理的过程中把对称加密和非对称加密都利用了起来。即利用了非对称加密安全性高的特点,又利用了对称加密速度快,效率高的好处。真的是设计得非常精妙,令人赞不绝口。

上一篇 下一篇

猜你喜欢

热点阅读