Http协议的相关概念

目录

HTTP协议

HTTP的发展

Web资源

HTTP协议的完整流程

请求

客户端

​编辑

响应

服务器

URI和URL

资源路径

动态资源

URL字符的要求

HTTP请求中的关键信息 

请求方法

演示1:通过

发送POST 请求

演示2:

ajax请求/xhr请求 

执行顺序

非常常见的一道面试题

面试题小结

演示3: 使用ajax发送post+携带请求体的请求

HTTP响应中的关键信息  

重定向

响应头

form表单提交

小结


HTTP协议

Web应用中的基本单位是Web资源。Web资源分布在网络中的任意主机上,所以本机的浏览器要获取这些Web资源,就必须通过一种网络协议——HTTP协议。

HTTP协议是以Web资源为基本单位。
每次请求-响应只能针对一个Web资源进行。

HTTP的发展

HTTP: Hyper(超)Text (文本)Transfer(传输)Protocol(协议)
HTTP协议设计肇始,是为了传输超文本(HTML的前身),随着互联网的发展,HTTP协议传输的不仅仅是超文本了,目前其实任意类型都可以。

围绕着超文本这套类型发展出来的前端三剑客(HTML、CSS、JavaScript)还是其主流;除此之外,其他多媒体资源也是非常常见的:图片、音频、视频等。

HTTP协议是一套应用层协议(一开始专注于业务,但现在HTTP协议本身也成为基础协议之一了),所以HTTP协议必须在一套传输层协议上进行传输。传输层的候选协议:UDP、TCP。
HTTP在1.0、1.1、2.0是基于TCP协议之上进行工作的。(HTTP协议中本身没有设计任何提供可靠性的机制,依赖传输层及以下网络已经提供可靠服务)
HTTP 在3.0之后,开始基于UDP协议上进行了。(HTTP协议内部自己做可靠性工作了)

HTTP协议的客户端,一般称为浏览器,同时又被称为用户代理(User-Agent)等名称,网景浏览器可以说是最早的浏览器了。

Web资源

Web资源:某些内容或者是执行一些动作,以服务的形式体现。购买一本书(书就是 web资源)、发个快递(发快递动作是web资源)。

HTTP协议的完整流程

重点是理解HTTP格式:请求格式和响应格式

请求

客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * 只能进行一次请求-响应的 HTTP 客户端
 */
public class MyHttpClient {
    public static void main(String[] args) throws IOException {
        // 主机       127.0.0.1
        // 端口       8080
        // 资源路径    /hello.html
        try (Socket socket = new Socket("127.0.0.1", 8080)) {
            // 准备 HTTP 请求内容
            // 文本   String
            // 格式:请求行
            String requestLine = "GET /hello.html HTTP/1.0\r\n";

            // 请求头:完全可以没有,但必须一个空行结尾
            // 请求头中共有 1对 key-value
            String requestHeader1 = "Name: xxx\r\n\r\n";
            // 请求头中共有 2对 key-value
            String requestHeader2 = "Name: xxx\r\nAge: 1993\r\n\r\n";
            // 请求头中共有 0 对 key-value
            String requestHeader3 = "\r\n";
            // 请求体,GET 是没有请求体

            // 最终的请求 —— 要发送给服务器的东西
            String request = requestLine + requestHeader3;

            // 发送服务器的过程
            byte[] requestBytes = request.getBytes("ISO-8859-1"); // 字符集编码

            // 发送(数据会经由 TCP、IP、以太网发送给服务器)
            OutputStream os = socket.getOutputStream();
            os.write(requestBytes);
            os.flush();

            // 请求既然已经发送,我们要做的就是等待响应
            InputStream is = socket.getInputStream();
            // 响应的前面字符集应该是 ISO-8859-1,后边是 UTF-8
            Scanner scanner = new Scanner(is, "UTF-8");
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
        }
    }
}

响应

服务器

import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MyHttpServer {
    public static void main(String[] args) throws Exception {
        // 我们也监听在 8080 端口上
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            while (true) {
                Socket socket = serverSocket.accept();  // 三次握手完成

                // 读取用户的请求 :这里就不管用户的请求了,一律采用相同的方式返回响应
                // 发送响应
                // Content-Type: 浏览器应该按照什么格式来看到我们响应的资源内容的(资源内容放在响应体中)
                // 响应体(资源的内容)
                String responseBody = "<h1>Welcome MyHttpServer</h1>";
                byte[] responseBodyBytes = responseBody.getBytes("UTF-8");
                int contentLength = responseBodyBytes.length;

                System.out.println("发送响应");
                // 响应头
                String response = "HTTP/1.0 200 OK\r\n"
                        + "Server: xxx\r\n"
                        + "Content-Type: text/plain; charset=utf-8\r\n"    // 响应体的类型
                        + "Content-Length: " + contentLength + "\r\n"      // 响应体的长度
                        + "\r\n";
                byte[] responseBytes = response.getBytes("ISO-8859-1");
                
                OutputStream os = socket.getOutputStream();
                // TCP 是面向字节流的一种协议,所以只要按顺序发即可,不要管分几次发送
                os.write(responseBytes);    // 先发送前面部分(响应行 和 响应头)
                os.write(responseBodyBytes);    // 再发送响应体
                os.flush();

                // 发送完成之后,直接关闭 TCP 连接(短连接的处理模式)
                socket.close();
            }
        }
    }
}

URI和URL

经常将ip(域名)+port 合起来称为主机 ( host)

资源路径

动态资源

URL字符的要求

HTTP请求中的关键信息 

1.请求方法
2.请求的资源路径

3.请求版本
4.请求头
5.可能存在的请求体

请求方法

演示1:通过<form>发送POST 请求

实验中涉及了两个web 资源

/post-form.html(静态资源)我们采用GET请求方法
/demo(动态)我们采用POST请求方法

演示2:

ajax请求/xhr请求 

重点!

通过JavaScript 发起HTTP请求——俗称ajax请求/xhr请求

我们使用比较频繁,尤其是在现代 web开发的前后端分离开发模式下。

使用方式(以下代码是JavaScript代码)︰

// 1. 实例化一个 XMLHttpRequest 对象,简称 XHR 对象
var xhr = new XMLHttpRequest()      // JS 语法下的实例化对象

// 2. 调用 对象 的 open(...) 方法,设置 发起请求的 1)方法   2)资源路径
//xhr.open('get', '/demo')    // GET /demo
xhr.open('post', '/demo')   // POST /demo

// 3. 设置回调函数,当 /demo 资源的响应返回时,应该干什么
// 通过事件绑定机制
// 事件源:xhr 对象
// 事件:load 事件(当响应返回时)
// 事件处理:回调函数
xhr.onload = function() {
    console.log(xhr.status)         // 打印响应的状态(成功是 200)
    console.log(xhr.responseText)   // 打印响应的响应体
    // 当然响应的其他信息我们都可以获取到,只是一般不关心
}

// 4. 真正发送请求出去
xhr.send()
<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>发起 ajax 请求</title>
</head>
<body>
    <!-- js 代码无法直接运行,必须挂靠在一个 html 上才可以 -->
    <!-- 浏览器会启动 GET /js/ajax-demo.js -->
    <!-- 并且在 JS 响应后运行 JS 代码 -->
    <!-- 运行代码过程中,会发 ajax 请求 GET /demo -->
    <!-- 最终是 3 个 HTTP 请求响应 -->
    <!-- GET /ajax-demo.html -->
    <!-- GET /js/ajax-demo.js -->
    <!-- GET /demo -->
    <script src="/js/ajax-demo.js"></script>
</body>
</html>

执行顺序

这些代码中有的是JS代码,有的是Java 代码;有的运行在浏览器进程中,有的运行在Tomcat 进程。但这些不重要的,重要的这些语句会按照一定的顺序执行。

请问执行顺序是什么∶
答:

非常常见的一道面试题

幂等性

面试题小结

演示3: 使用ajax发送post+携带请求体的请求

GET在query string中无论携带什么数据,总体上还是得遵守key=value的形式。但post则非常灵活。

使用ajax发送post+携带请求体的请求。

@Controller
public class MyController {
    @RequestMapping("/collect")
    @ResponseBody
    public String collect() {
        return "OK";
    }
}
var xhr = new XMLHttpRequest()
xhr.open('post', '/collect')
xhr.onload = function() {
    console.log(xhr)
    console.log(this)
}

// 区别在这里
xhr.setRequestHeader('Content-Type', 'text/xxxxxxx')
xhr.send('我随便写,按照 content-type 的格式去写就行')
<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>发送有请求体的 ajax 请求</title>
</head>
<body>
    <script src="/js/ajax-send-request-body.js"></script>
</body>
</html>

form表单逻辑上只是一种提交数据的形式。但实际中使用较多,所以form提交的一些行为,代替了get/post 请求的行为。

HTTP响应中的关键信息  

重定向

重定向分类

 

同理,通过 ajax发起HTTP 404或者其他错误,你是无法在页面中直接看到错误的,所以打开开发者工具去查看。

响应头

form表单提交

总之,文件上传时(通过form表单上传),必须指定enctype为multipart/form-data这样,请求体中才不仅仅携带要上传文件的文件名,还包含文件内容信息。这样,后端才可以读取到信息,做进—步处理。

小结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
HAProxy 是一款高性能、开源的负载均衡软件,支持 TCP/HTTP 应用的负载均衡。在了解 HAProxy 的相关概念之前,需要先了解几个基本概念: 1. 前端(Frontend):HAProxy 可以监听多个端口,每个监听端口对应一个前端。前端可以是一个 IP 地址和端口号的组合,也可以是一组已经绑定的 IP 地址和端口号。 2. 后端(Backend):后端是一组服务器的集合,这些服务器通常运行相同的应用程序,HAProxy 可以将请求从前端路由到后端,并进行负载均衡。 3. 服务器(Server):服务器是后端中的一个成员,可以是物理服务器、虚拟机或容器等。 4. 监听器(Listener):监听器是一种特殊的前端,它可以在单个端口上监听多个协议。例如,可以在 80 端口上同时监听 HTTPHTTPS。 5. ACL(Access Control List):ACL 是一种用于控制访问的规则,可以根据来源 IP 地址、请求路径、请求头等条件对请求进行分类和过滤。 6. 负载均衡算法:负载均衡算法用于将请求分配到后端服务器。常见的负载均衡算法包括轮询(Round Robin)、最少连接(Least Connections)、IP 哈希(IP Hash)等。 在 HAProxy 中,可以通过配置文件来定义前端、后端、服务器、监听器、ACL 和负载均衡算法等。HAProxy 的配置文件通常位于 /etc/haproxy/haproxy.cfg,可以使用任何文本编辑器来编辑。需要注意的是,在修改配置文件之前应该备份原来的配置文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瘦皮猴117

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值