HTTP协议与HTTPS

目录

1.了解HTTP协议

2.HTTP协议的报文格式

1)请求报文格式

2)响应报文格式

3)报文格式的注意事项

3.认识URL

        1)分析一个具体的URL

        2)URL中可省略的部分

        3)关于URL encode和URL  decode

4.HTTP请求(Request)

        1)GET方法

        2)POST方法

        3)其他相关方法

5.认识请求报头(header)

6.HTTP响应(Response)

        1)认识状态码(status  code)

        2)认识响应正文(body)

7.构造HTTP请求

1)通过form表单构造HTTP请求

2)通过ajax构造HTTP请求

8.HTTPS

1)什么是HTTPS

2)为什么引入HTTPS

3)HTTPS的工作流程

4)HTTPS传输过程

 谈谈 GET 和 POST 的区别


1.了解HTTP协议

HTTP (HyperText Transfer Protocol, 超文本传输协议) 是一种应用非常广泛的 应用层协议.

所谓“超文本”的含义,就是传输的内容不仅仅是文本(比如html,css这个就是文本),还可以是一些其他资源,比如图片,视频,音频等二进制  的数据

2.HTTP协议的报文格式

1)请求报文格式

首行:【方法】【URL】【版本】

空行

Body:空行后面的内容为Body

2)响应报文格式

首行:【版本号】【状态码】【状态码的解释】

Header:请求的属性

空行

Body:空行后面的内容Body

3)报文格式的注意事项

1.首行的内容之间有一个空格

2.请求的属性是使用冒号分割是键值对

每组属性之间使用\n分割

遇到空行表示Header部分结束

3.Body允许为空

如果Body存在,Header中会有一个Content-Length属性来标识Body的长度

4.协议格式总结

HTTP协议与HTTPS_第1张图片

3.认识URL

        1)分析一个具体的URL

https://dict.youdao.com/result?word=1&lang=en

https:协议方案名

user:pass:登录信息,目前一般会省略

dict.youdao.com:服务器地址,此处是一个“域名”,域名会通过DNS系统解析成一个具体的IP地址 

端口号:目前一般会省略,http协议默认使用80端口,https协议默认使用443端口

/result:带层次的文件路径

Word=1&lang=en:查询字符串(query  string),本质是一个键值对结构,键值对之间使用&分割,键和值之间使用=分割

片段标识:此URL中省略了片段标识,片段标识主要用于页面跳转

        2)URL中可省略的部分

协议名:可以省略,省略后默认为http://

ip地址/域名:在HTML中可以省略,省略后表示服务器的ip/域名与当前的HTML所属的ip/域名一致

端口号:可以省略,省略后如果是http协议,端口号自动设为80;如果是https协议,端口号自动设为443

带层次的文件路径:可以省略,省略后相当于/,有些服务器会在发现/路径的时候自动问/index。html

查询字符串:可以省略

片段标识:可以省略

        3)关于URL encode和URL  decode

像“/  ?  :  =  &”等这样的字符,已经被URL当做特殊意义理解了,因此这些字符不能随意出现

把特殊字符,转换成转义字符  => URL  encode

把转义字符,还原成原来的字符  =>  URL  decode

4.HTTP请求(Request)

        1)GET方法

 构造HTTP  GET请求的情况

1.直接在浏览器中输入URL

2.HTML中的link,img,a,script标签等

3.from表单

4.ajax

5.使用Java代码/其他的库

6.通过Linux下的wegt/curl

7.通过第三方工具,postman这类工具

GET请求的特点

1.首行的第一部分为GET

2.URL的query  string 可以为空,也可以不为空

3.header部分有若干个键值对结构

body部分为空(也可以不为空)

        2)POST方法

构造HTTP  POST请求的情况

1.form表单

2.ajxa

3.第三方工具

POST请求的特点

1.首行的第一部分为POST

2.URL的query  string 一般为空(也可以不为空)

3.header部分有 若干个键值对结构

4.body部分一般不为空,body内的数据格式通过header中Content-Type指定body的长度由header中的Content-Length指定

        3)其他相关方法

  • PUT 与 POST 相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用

5.认识请求报头(header)

header的整体的格式也是“键值对”结构,每个键值对占一行,键和值之间使用分号分割

        1)Host:表示服务器主机的地址和端口

        2)Content-Length:表示body中数据长度

        3)Content-Type:表示body中的数据格式的类型

                1.application/x-www-form-urlencoded:在 form 表单提交的时候会出现的数据格式类型.

                2.multipart/form-data:通常用于提交图片/文件

                3.application/json

        4)User-Agent:字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器

        5)Referer:表示这个页面是从那个页面跳转过来的,如果直接在浏览器中输入URL,或直接通过收藏夹访问页面时是没有Referer的

        6)Cookie:因为HTTP是无状态的协议,无法根据之前的状态进行本次的请求处理,为了保留无状态协议这个特征,于是引入了Cookie信息来控制客户端的状态,Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存,Cookie当下次再给该服务器发送请求的时候,客户端会自动再请求报文中加入Cookie值后发送出去,服务器端发现客户端发送来的Cookie后,会去检查是哪一个客户端发送来的连接请求,对比服务器上的记录,最后得到之前的状态信息

HTTP协议与HTTPS_第2张图片

认识请求正文(body)

        1)  application/x-www-form-urlencoded

        2) multipart/form-data

        3)application/json

6.HTTP响应(Response)

        1)认识状态码(status  code)

200  OK:这是一个最长见的状态码,表示访问成功

404 Not  Found:没有找到资源

403 Forbidden:表示访问被拒绝,有的页面通常需要用户具有一定的权限才能访问(登录后才能访问),如果用户没有登录直接访问,就容易见到403

500  Internal  Server  Error:服务器出现内部错误,一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会出现这个

302 Move temporarily:临时重定向,重定向就和呼叫转移一样(就相当于换了个手机号,别人呼叫你的旧手机号,会自动转到新手机号上)

        2)认识响应正文(body)

正文的格式取决于Content-Type

text/html:body中数据格式是html

text/css:body中数据格式是css

application/JavaScript:body中数据格式是Javascript

application/json:body中数据格式是json

7.构造HTTP请求

1)通过form表单构造HTTP请求

构造GET请求:

    

构造POST请求

    

2)通过ajax构造HTTP请求

发送GET请求

    

发送POST请求

    

通过第三方库来封装ajax

    
    

通过Java  socket构造HTTP请求

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class HttpClient {
    private Socket socket;
    private String ip;
    private int port;

    public HttpClient(String ip,int port) throws IOException {
        socket = new Socket(ip,port);
        this.port = port;
        this.ip = ip;
    }

    public String get(String url) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("Get " + url + " HTTP/1.1\n");
        // 构造 header
        request.append("Host: " + ip + ":" + port + "\n");
        // 构造空行
        request.append("\n");
        // GET 不需要 body, 构造完毕
        OutputStream outputStream = socket.getOutputStream();
        // outputStream 是一个字节流,以字节为单位进行写入,因此需要把 StringBuilfer 转换乘byte[]
        outputStream.write(request.toString().getBytes());

        // 读取响应
        InputStream inputStream = socket.getInputStream();
        // 1M 大小的缓冲区,用来存放响应数据
        byte[] buffer = new byte[1024 * 1024];
        // n 表示实际上读到的字节数
        int n = inputStream.read(buffer);
        return new String(buffer,0,n,"utf-8");
    }

    public String post(String url,String body) throws IOException {
        StringBuilder request = new StringBuilder();
        // 构造首行
        request.append("POST" + url + "HTTP/1.1\n");
        // 构造header
        request.append("Host: " + ip + ":" + port + "\n");
        request.append("Content-Type: text/plain\n");
        request.append("Content-Length: " + body.getBytes().length + "\n");
        // 构造空行
        request.append("\n");
        // 构造 body
        request.append(body);

        // 发送请求
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(request.toString().getBytes());

        // 读取响应
        InputStream inputStream = socket.getInputStream();
        byte[] buffer = new byte[1024 * 1024];
        int n = inputStream.read(buffer);
        return new String(buffer, 0, n, "utf-8");
    }

    public static void main(String[] args) throws IOException {
        HttpClient httpClient = new HttpClient("42.192.83.143",9090);
        String resp = httpClient.get("/AjaxMockServer/info");
        System.out.println(resp);
//        String resp = httpClient.post("/AjaxMockServer/info","这是正文");
//        System.out.println(resp);
    }
}

8.HTTPS

1)什么是HTTPS

HTTPS也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层(SSL/TLS)

2)为什么引入HTTPS

因为HTTP是明文传输,本来要传什么,实际上就传了什么,但是一旦这样传输,在传输的过程中,被第三方截获到了,就可能造成信息泄露,于是就引入了HTTPS在HTTP基础上进行了加密,进一步的保护了用户的信息安全

明文:真正要传输的信息

密文:加密之后的消息

加密:就是把明文进行一系列变换,生成密文

解密:就是把密文在进行一系列变换,还原成明文

在这个加密和解密的过程中,往往需要一个或者多个中间的数据,辅助进行这个过程,这样的数据称为密钥

3)HTTPS的工作流程

        引入对称加密

对称加密其实就是通过同一个“密钥”,把明文加密成密文,并且也能把密文解密成明文

        引入非对称加密

非对称加密要用到两个密钥,一个叫做“公钥”,一个叫做“私钥”

公钥和私钥是配对的,最大的缺点就是运算速度非常慢,比对称加密要慢很多

此时也有一个问题,可能在获取的公钥就是假的

解决办法:引入证书

        引入证书

在客户端和服务器刚一建立连接的时候,服务器给客户端返回一个证书,这个证书包含了刚才的公钥,也包含了网站的身份信息

当客户端获取到这个证书之后,会对证书进行校检(防止证书是伪造的)

1)判断证书的有效期是否过期

2)判断证书的发布机构是否受信任

3)要验证是否被篡改:从系统中拿到该证书发布机构的公钥,得到一个hash值(称为数据摘要),设为hash1,然后计算整个证书的hash值,设为hash2,对比hash1和hash2是否相等,如果相等,则说明证书是没有被篡改过的

4)HTTPS传输过程

客户端先从服务器那边获取到证书,证书里包含了公钥

客户端对整数进行校检

客户端生成一个对称密钥,使用公钥对对称密钥进行加密,发送给服务器

服务器得到这个请求后,使用私钥解密,得到对称密钥

客户端发出后续的请求,后续的请求都是使用这个对称密钥加密的,收到的数据也都是使用这个对称密钥解密的

 谈谈 GET 和 POST 的区别

GET和POST之间本质上没有区别

数据位置: GET 把自定义数据放到 query string, POST 把自定义数据放到 body
语义区别: GET 一般用于"获取数据",POST 一般用于提交数据
幂等性: GET 请求一般会设计成"幂等". POST 请求一般不要求设计成"幂等"(如果多次请求得到的结果一样, 就视为请求是幂等的)
可缓存: GET 请求一般会被缓存 POST 请求一般不能被缓存
 

你可能感兴趣的:(http,https,网络协议)