• ajax之Content-Type示例


    参考资料:

    1. Content-Type详解
    2. 【SpringBoot】SpringBoot接收请求的n种姿势
    3. Http中的Content-Type详解
    4. HTTP Content-type常用对照表


    前期准备

    ⏹html

    DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    head>
    <body>
        <div>
            <form id="form" action="/test15/receiveRequest" method="post">
                 <label for="name">姓名label><input id="name" type="text" name="name" value="贾飞天" /><br>
                 <label for="hobby">爱好label><input id="hobby" type="checkbox" name="hobby" checked="checked" /><br>
                 <label for="address">地址label><select id="address" name="address">
                    <option value="1">山东省option>
                    <option value="2">广东省option>
                    <option value="3">广西省option>
                select>
                <button>表单方式提交button>
            form>
            <button id="ajax-submit">Ajax方式提交button>
        div>
    body>
    <script type="text/javascript" th:src="@{/js/public/jquery-3.6.0.min.js}">script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    ⏹JS

    // 工具函数,将form表单转换为json数据
    const serialize = (formEle) => Array.from(new FormData(formEle)).reduce((p, [k, v]) => Object.assign({}, p, { [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v }), {});
    
    // 后台url
    const url = "/test15/receiveRequest";
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ⏹form

    import lombok.Data;
    
    @Data
    public class Test15Form {
    
        private String name;
    
        private String hobby;
    
        private String address;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ⏹controller

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    @Controller
    @RequestMapping("/test15")
    public class Test15Controller {
    
    	// XXX省略init方法XXX
    
        @PostMapping("/receiveRequest")
        @ResponseBody
        public void receiveRequest(Test15Form form) {
    
            System.out.println(form);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    0. Content-Type概念解释

    HTTP协议消息头中,使用Content-Type来表示媒体类型信息。它被用来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析html或仅仅展示一个文本等。

    Post请求的内容放置在请求体中,Content-Type定义了请求体的编码格式。数据发送出去后,还需要接收端解析才可以。接收端依靠请求头中的Content-Type字段来获知请求体的编码格式,最后再进行解析。

    ⏹常见的Content-Type有如下三种 :

    1. application/x-www-form-urlencoded

    • 浏览器原生的form表单类型,或者说是表单默认的类型。
    • jQuery的ajax不指定contentType的话,默认就是application/x-www-form-urlencoded
    • Spring直接使用表单对应的实体类接收即可,不需要@RequestBody注解

    1.1 form表单示例

    后台controller接收,直接使用和Form表单对应的实体类接收即可

    @PostMapping("/receiveRequest")
    @ResponseBody
    public void receiveRequest(Test15Form form) {
    
        System.out.println(form);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    在这里插入图片描述

    1.2 jQuery的ajax示例

    $("#ajax-submit").click(function() {
    	
    	// 将表单转换为对象
        const jsonData = serialize($("#form").get(0));
    
        $.ajax({
            url: url,
            type: 'POST',
            // 直接提交对象
            data: jsonData,
            // 指定contentType类型
            // 注意: 如果将此代码注释掉,不指定contentType
            // 默认就是application/x-www-form-urlencoded类型
            contentType: 'application/x-www-form-urlencoded',
            success: function (data, status, xhr) {
                console.log(data);
            }
        });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    2. application/json

    • ⏹如今大部分的请求都会以json形式进行传输,post会将序列化后的json字符串直接塞进请求体中。
    • contentType: 'application/json;charset=utf-8'@RequestBody注解对应,Spring需要使用@RequestBody注解,来将请求体中的json字符串转化为java对象
    $("#ajax-submit").click(function() {
    
        const jsonData = serialize($("#form").get(0));
    
        $.ajax({
            url: url,
            type: 'POST',
            // 对象转换为json字符串
            data: JSON.stringify(jsonData),
            // 指定发送的是json字符串
            contentType: 'application/json;charset=utf-8',
            success: function (data, status, xhr) {
                console.log(data);
            }
        });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    在这里插入图片描述

    2.1 指定contentType为json,不使用@RequestBody接收

    • ⏹无法接收到数据

    在这里插入图片描述

    2.2 不指定contentType,使用@RequestBody接收

    • 报错: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

    ⏹前台

    $.ajax({
        url: url,
        type: 'POST',
        // 对象转换为json字符串
        data: JSON.stringify(jsonData),
        // 省略了contentType
        success: function (data, status, xhr) {
            console.log(data);
        }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ⏹后台

    @PostMapping("/receiveRequest")
    @ResponseBody
    public void receiveRequest(@RequestBody Test15Form form) {
    
        System.out.println(form);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ⏹效果

    在这里插入图片描述

    3. multipart/form-data

    • 用于在表单中上传文件,将文件和表单数据共通提交到后台
    • 因为不是application/json,所以无法使用@RequestBody注解接收
    • jQuery的contentType不能设置为multipart/form-data,需要设置为false

    ⏹前台-html

    DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    head>
    <body>
        <div>
            <form id="form">
            
                <label for="name">姓名label><input id="name" type="text" name="name" value="贾飞天" /><br>
                <label for="hobby">爱好label><input id="hobby" type="checkbox" name="hobby" checked="checked" /><br>
                <label for="address">地址label>
                <select id="address" name="address">
                    <option value="1">山东省option>
                    <option value="2">广东省option>
                    <option value="3">广西省option>
                select><br>
    			
    			
                <input type="file" name="fileList">
                <input type="file" name="fileList">
                
            form>
            <button id="ajax-submit">Ajax方式提交button>
        div>
    body>
    <script type="text/javascript" th:src="@{/js/public/jquery-3.6.0.min.js}">script>
    html>
    
    • 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

    ⏹前台-JS

    const url = "/test15/receiveRequest";
    
    $("#ajax-submit").click(function() {
    	
    	// 使用FormData来获取表单中的数据
        const formData = new FormData($("#form").get(0));
        
        $.ajax({
            url: url,
            type: 'POST',
            // 注意提交的不是表单对象,而是FormData对象
            data: formData,
            /*
            	告诉jQuery不要去设置Content-Type请求头
            	FormDate对象是XMLHttpRquest2的类型,利用XHR对象发送FormDate生成的数据时,可以直接发送,不需要设置头部,
            	XHR对象能够会自动识别数据类型是FormDate的实例,并配置相关的头部.
    		*/
            contentType: false,
            /*
               	jQuery的ajax()方法发送的数据默认是序列化后的字符串,因此processData的值默认为true
               	我们要同时传输文件和表单数据,所以将contentType设置为false,告诉jQuery不要将要发送的数据处理为字符串
    		*/
    	    processData: false,
            success: function (data, status, xhr) {
                console.log(data);
            }
        });
    });
    
    • 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

    ⏹前台-form

    import java.util.List;
    
    @Data
    public class Test15Form {
    
        private String name;
    
        private String hobby;
    
        private String address;
    
        private List<MultipartFile> fileList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Spring Security(十九)--OAuth2:实现授权服务器(下)--环境准备以及骨架代码搭建
    UiPath实战(08) - 选取器(Selector)
    C++ —— 编写Windows钩子,完成屏蔽系统win+d显示/隐藏窗口功能(win功能不影响)。(附完整源码)
    Mybatis 框架理解与快速入门详解
    国产高云FPGA开发软件Gowin的下载、安装、Licence共享,按照我的方案保证立马能用,不能用你铲我耳屎
    统一异常ServiceException
    day5_redis学习
    Jmeter如何进行接口测试-实操
    面试题——网址 (url) 的组成、url模块、querystring模块、mime模块、各种路径、静态资源托管、网页的加载流程
    vue 项目的屏幕自适应方案
  • 原文地址:https://blog.csdn.net/feyehong/article/details/128054083