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>Title</title>
</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>

⏹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";

⏹form

import lombok.Data;

@Data
public class Test15Form {

    private String name;

    private String hobby;

    private String address;
}

⏹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);
    }
}

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 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);
        }
    });
});

在这里插入图片描述

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);
        }
    });
});

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

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);
    }
});

⏹后台

@PostMapping("/receiveRequest")
@ResponseBody
public void receiveRequest(@RequestBody Test15Form form) {

    System.out.println(form);
}

⏹效果

在这里插入图片描述

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>Title</title>
</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>
			
			<!-- 两个文件上传框的name相同,可以将两个文件作为一组封装到一个List中 -->
            <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>

⏹前台-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);
        }
    });
});

⏹前台-form

import java.util.List;

@Data
public class Test15Form {

    private String name;

    private String hobby;

    private String address;

    private List<MultipartFile> fileList;
}

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值