• 构造 HTTP 请求


    一、通过 form 表单构造 HTTP 请求(常用)

    通过 form 表单构造 HTTP 请求,需要写在一个 html 文件内。
    使用 form 标签 + input 标签,两者配合。

    展示1

    <body>
        <form action="https://www.baidu.com" method="GET">
            <input type="text" name="ClassID" >
            <input type="text" name="StudentID">
            <input type="submit" value="提交">
        form>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    展示结果:

    1

    展示2

    <body>
        <form action="https://www.baidu.com" method="POST">
            <input type="text" name="ClassID" >
            <input type="text" name="StudentID">
            <input type="submit" value="提交">
        form>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    展示结果:

    2

    总结

    form 表单的重要参数:
    action:构造 HTTP 请求的 URL
    method:构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST)

    input 标签的重要参数:
    type:表示输入框的类型。text 表示文本,password 表示密码, submit 表示提交按钮。
    name:表示构造出的 HTTP 请求的 query string 的 key,而 query string 的 value 就是输入框对应的用户输入内容。
    value:input 标签的值,对于 type 为 submit 类型来说,value 就对应了按钮上显示的文本。

    二、通过 ajax 构造 HTTP 请求(常用)

    1. ajax 背景

    ajax:Asynchronous JavaScript and XML

    ajax 是 是 2005 年提出的一种 JavaScript 给服务器发送 HTTP 请求的方式。

    其中,Asynchronous 表示异步的意思。

    备注:

    由于 ajax 的原生用法较为麻烦,工作中也不太可能用到,所以,我们就通过 JS 引入第三方库 jQuery. jQuery 其实是一个功能非常全面的库,它对 DOM API 进行了非常好的封装。我们只需要在 JS 代码中,引入 jQuery 所在的网络地址,就能直接使用,当然,如果下载到本地,也是可以使用的。(这种方式较为稳定,更为推荐)

    jQuery:JavaScript 中最知名,最广泛使用的第三方库之一。

    2. ajax 构造请求的代码格式

    <body>
        
        <script src="js/jquery.min.js">script>script>
        <script>
            //ajax 方法传参传的是一个大括号对象
            $.ajax({
               // url 中填写需要访问的服务器地址
               url: '', 
               //这就表示一个 GET 方法
               method: 'GET', 
    
               //data 就是响应的 body,status 就是响应的状态码
               success: function(data, status) {
                    
               } 
               error: function(data, status) {
    
                }
            });
        script>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    分析上面的代码:

    ① $ 表示 jQuery 中已经定义好的一个对象 / 变量,虽然美元符号看上去很奇怪,但它语法上确实能作为一个变量。

    ② ajax 是一个方法,往这个方法传参传的是一个大括号对象,其中包含了 type, url…

    ③ type 表示 HTTP 请求中,首行的请求方法的类型,GET / POST / PUT… 此外,method 也可以表示各种各样的方法,和 type 的作用一样

    ⑤ url 中填写需要访问的服务器地址

    ⑥ success 表示请求成功的回调函数,即并非自己调用,等浏览器自动来调用,在 success 这个回调函数中,一般都是用来展示最后的 html 页面,即前端开发人员决定在这里面实现什么给用户看。

    ⑦ 上面是通过 jQuery 库,来实现 ajax 构造 HTTP 请求的基本格式,这里没办法展示,因为,url 中需要填写和代码配合的服务器,否则就会出错。

    ⑧ 在浏览器页面加载过程中,是可以同时发起多个 ajax 请求的,此时这多个 ajax 请求相当于是一个并发执行的关系。

    3. 理解 success 回调函数

    ① 关于 success 这个回调函数:顾名思义,它表示从客户端发送 HTTP 请求成功后,浏览器调用此函数。一般来说,success 其实就意味着 HTTP 响应的状态码是 200. 也就是说,只有 HTTP 请求发送成功后,success 才能被浏览器执行。

    ② 回调函数并不是自己调用,而是让浏览器在合适的时机自己调用的,这一点需要格外注意。

    ③ 一般来说,success 这个回调函数中,需要写入的业务逻辑,一般就是为了展示给用户观看的内容。即前端开发人员决定在这里面实现什么给用户看。

    问1:那么业务逻辑的数据从哪来?
    答:业务逻辑的数据就是从 success 函数中,传入的参数 data 中获取到的。

    问2:那么 data 从哪来?
    答:data 就是从 HTTP 响应的正文 body 来获取的。

    问3:正文 body 又从哪来?
    答:HTTP 响应的正文 body 其实就是服务器端的代码构造的,常用的就是 json 格式数据,因为 json 格式的数据是可以将很多复杂的文本组合在一起。所以,后端的开发人员,一般通过将 Java 对象转换成 json 格式的数据,放到 响应的 body 中。

    4. error 回调函数

    上面说到,success 一般对应着 状态码 200,而 error 一般对应着 除 200 之外的状态码 ( 例如 403 权限状态码 )。

    因为顾名思义,在回调函数的业务逻辑中,就是用来处理【客户端发送 HTTP 请求失败的情况】,这些情况可能是路径问题,可能是密码错误问题,也可能是用户权限问题等等…

    5. ajax 跨域问题 (了解)

    另外,上面的代码还会出现跨域问题。因为 ajax 为了保证安全性,要求发起 ajax 请求的页面和接收 ajax 请求的服务器,应该在同一个域名 / 地址下。

    假设,发起请求的页面对应的域名为域名1,接收ajax 请求的服务器的域名为域名2,如果 域名1 和 域名2 不相同,就认为是一次跨域请求。
    比方说:百度下面的 html 中的 ajax 就不能访问 搜狗 的服务器。这就好像是串台了一样…

    而上面的代码是在本地编辑的代码,如果真的需要和服务器配合,那么,服务器端就需要在响应中,通过代码加上一些 header 响应报头,做出解除跨域的限制,在这之后,客户端才能与服务器进行正常的交互。

    三、通过 Postman 软件来构造请求(推荐)

    1. 一个简单的前后端交互

    Postman 是一个软件,感兴趣的小伙伴可以自己下载看一看,一用就会。

    利用 Postman 软件构造前端请求:

    7-1

    创建一个 Spring Boot 项目构造后端代码:

    @Controller
    public class TestController {
        @ResponseBody
        @RequestMapping("/hi")
        public String hello() {
            return "Hi, postman!";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. Postman 的软件功能

    ① 可以构造多种 HTTP 方法
    ② 可以保存曾经访问的 URL
    ③ 可以按照自己的需求,发送不同格式的正文 ( json / form-data…)
    ④ 可以自定义 header 请求头

    四、通过 Java socket 构造 HTTP 请求(用的极少)

    所谓 " 发送 HTTP 请求 ",本质上就是按照 HTTP 的格式往 TCP Socket 中写入一个字符串。所谓 " 接收 HTTP 响应 ",本质上就是从 TCP Socket 中读取一个字符串,再按照 HTTP 的格式来解析。我们可以基于 Socket 的知识,构造出一个简单的 HTTP 客户端程序,用来发送各种类型的 HTTP 请求。

    所以,只要我们理解了 HTTP 协议的请求和响应格式,就明白,协议本身就是一个拼接字符串的效果,而使用 Java 代码写出来的原理也是拼接字符串。

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class HttpClient {
        private Socket socket;
        private String ip;
        private int port;
    
        public HttpClient(String ip, int port) throws IOException {
            this.ip = ip;
            this.port = port;
            socket = new Socket(ip, port);
        }
    
        /**
         * 模拟 GET 方法
         */
        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 是一个字节流,以字节单位写入
            // 所以需要把 StingBuilder 类型转换成 String 类型,再转换成 byte[]
            outputStream.write(request.toString().getBytes());
    
            // 读取响应数据
            InputStream inputStream = socket.getInputStream();
            // 创建一个 1M 大小的缓冲区,用来存放响应数据
            byte[] buffer = new byte[1024 * 1024];
            int n = inputStream.read(buffer);
            return new String(buffer, 0, n, "utf-8");
        }
    
        /**
         * 模拟 POST 方法
         */
        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-Length: " + body.getBytes().length + "\n");
            request.append("Content-Type: text/plain\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("123",8080); //这里需要指定需要访问服务器的 IP 和 端口
            String getResp = httpClient.get(""); //填写请求的 url
            System.out.println(getResp);
    
            String postResp = httpClient.post("", "this is body"); //填写请求的 url 和 body 正文
                    System.out.println(postResp);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    另外,使用 Java 构造的 HTTP ,客户端不再有 " 跨域 " 的限制了,此时客户端也可以获取其他服务器的数据了。跨域只是浏览器的行为,对于 ajax 有效,而对于其他语言来说,一般都和跨域无关。

  • 相关阅读:
    leetcode-136. 只出现一次的数字
    通达OA的开发模式
    scrapy框架搭建
    CFCA企业版通配符SSL证书
    项目实战之安装依赖npm install
    【Spring】bean的基础配置
    Http请求参数类型及servlet获取方式
    【记一次vsan数据救援的经历】
    [JS]学习笔记2 -- JAVAScript数据类型
    网络故障 ICMP UDP
  • 原文地址:https://blog.csdn.net/lfm1010123/article/details/126339874