三种常见的http content-type详解

2023-05-16

介绍

        http协议是建立在tcp/ip协议之上的应用层协议,主要包括三个部分,状态行,头部信息,消息主体。对应一个http请求就是:请求行,请求头,请求体。

        协议规定post提交的数据,必须包含在消息主体中entity-body中,但是协议并没有规定数据使用什么编码方式。开发者可以自己决定消息主体的格式。

        数据发送出去后,需要接收的服务端解析成功,一般服务端会根据content-type字段来获取参数是怎么编码的,然后对应去解码。

        在最早的http post请求中,只支持application/x-www-form-urlencoded,参数都是通过浏览器的url传递。其实是不支持文件上传的,这样有很多不便。在1995年的时候,出台了rfc1867,也就是《RFC 1867 From-based file upload in HTML》,用以支持文件上传。所以content-type扩充了multipart/form-data用以支持向服务器发送二进制数据。后来随着web应用的增多,增加了诸如application/json的类型。

application/x-www-form-urlencoded

        在最开始的请求方式中,请求参数都是放在url中,表单提交的时候,都是以key=&value=的方式写在url后面。这也是浏览器表单提交的默认方式。

        此时可以直接调用request.getInputStream或request.getReader获取到请求内容,再解析出具体的参数。后者只是对前者的一个封装,可以让调用者更方便字符内容的处理。可以看到:

	@Override
	public BufferedReader getReader() throws IOException {
		if (this.reader == null) {
			this.reader = new BufferedReader(new InputStreamReader(getInputStream(), 
getCharacterEncoding()));
		}
		return this.reader;
	}
    public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
        super(in);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }

        也可以通过request.getParameter获取到参数。

        但是需要注意,getInputStream、getReader、getParameter在一定的场景是互斥的

multipart/form-data

        此种方式多用于文件上传,表单数据都保存在http的正文部分,各个表单项之间用boundary分开。

        一次完整的抓包如下:

POST /ecard/uploadFaceImage?timestamp=1531906535406 HTTP/1.0
Host: www.example.com
X-Real-IP: 183.156.142.242
X-Forwarded-For: 183.156.142.242
Connection: close
Content-Length: 230101
sign: 9a7d3b4978979ef65a12e34ae1cf7b2d
accept: */*
user-agent: Mozilla/5.0 (Linux; U; Android 6.0.1; zh-CN; OPPO R9s Build/MMB29M) 
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 
UCBrowser/11.8.8.968 UWS/2.13.1.42 Mobile Safari/537.36 UCBS/2.13.1.42_180629181124 
ChannelId(1) NebulaSDK/1.8.100112 Nebula AlipayDefined(nt:WIFI,ws:360|0|3.0) 
AliApp(AP/10.1.28.560) AlipayClient/10.1.28.560 Language/zh-Hans useStatusBar/true 
isConcaveScreen/false
Cookie: ssl_upgrade=0; spanner=6tlJA6NZwnkqTDN+BMhdT7lbzLPsFJUeXt2T4qEYgj0=
Accept-Encoding: gzip
Content-Type: multipart/form-data; boundary=pgRq9HriiaBmfSo5rfyEJPtcumxb4fd6o15f_3G

--pgRq9HriiaBmfSo5rfyEJPtcumxb4fd6o15f_3G
Content-Disposition: form-data; name="personCode"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit

DM1203
--pgRq9HriiaBmfSo5rfyEJPtcumxb4fd6o15f_3G
Content-Disposition: form-data; name="DM1203"; filename="123524587.jpg"
Content-Type: 
Content-Transfer-Encoding: binary
  图片二进制数据(特别长)
--pgRq9HriiaBmfSo5rfyEJPtcumxb4fd6o15f_3G--
HTTP/1.1 200 
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Origin, No-Cache, X-Requested-With, 
If-Modified-Since, Pragma, Cache-Control, Expires, Content-Type
Access-Control-Allow-Credentials: true
XDomainRequestAllowed: 1
Content-Type: application/json;charset=UTF-8
Date: Wed, 18 Jul 2018 09:35:36 GMT
Connection: close

{"retCode":1,"msg":"success","data":null}

        可以看到里面有一个boundary分界,值为:pgRq9HriiaBmfSo5rfyEJPtcumxb4fd6o15f_3G,请求时,会放在Content-Type后面传到服务器,服务器根据这个边界解析数据,划分段,每一段都是一项数据。每一项中的name属性就是唯一的id

        此时用request.getParameter是取不到数据的,这个时候需要通过request.getInputStream来获取数据。这时取到的是一个InputStream,无法直接取到指定的表单项。但是有很多开源的组件可以直接利用,比如apache的fileupload组件。通过这些开源的upload组件,提供的api,就可以直接从request中取得指定的表单项。

ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> list = upload.parseRequest(request);

        上面的代码中,接下来就可通过遍历list获取参数了。

application/json

        现在越来越多的应用使用application/json,用来告诉服务端消息主体是序列化的json字符串。由于json规范的流行,各大浏览器都开始原生支持JSON.stringfy。

        而且spring对这个content-Type上传的数据有很好的支持,可以直接通过@RequestBody进行接收。也是当前完美适配当前流行的RestApi。

参考

Multipart/form-data POST文件上传详解

MVC实现,使用form-data传递数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三种常见的http content-type详解 的相关文章

  • 无法在服务器端 NodeJS 启用 CORS

    我无法启用CORS在服务器端 我的前端和后端服务器有不同的端口 服务器端的实现方式如下 http createServer function req res Here you can create your data response in
  • 尝试将过滤器添加到 Grizzly+Jersey 应用程序时出现问题

    我有这个服务器初始化类 package magic app main import org glassfish grizzly http server HttpServer import org glassfish jersey grizz
  • python http 客户端卡在 100 continue

    我在 python 中有一个简单的 http 服务器 它使用 100 continue 实现 PUT class TestHandler SimpleHTTPRequestHandler def do PUT self length int
  • 使用 HTML 表单时如何在 HTTP 请求正文中发送数据?

    HTTP 规范规定 POST 请求可以包含任意数据体 An HTML form元素可以 POST 到 URL 并且可能包含input元素 但那些input元素变成查询字符串 我怎样才能得到一个form还可以在按下提交按钮时发送的 HTTP
  • 为什么 HttpClient 使套接字保持打开状态?

    在创建 使用和处置多个 HttpClient 时 我注意到有套接字处于 TIME WAIT 状态 例如 运行以下命令后 using System Net Http namespace HttpClientTest public class
  • Express.js在控制器中获取http方法

    我正在构建一个注册表单 本地护照作为身份验证 表单作为表单助手 因为注册只知道 GET 和 POST 我想在一个函数中完成整个处理 换句话说 我正在寻找类似的东西 exports register function req res if r
  • Non-Authoritative-Reason 标头字段 [HTTP]

    当我有响应标头时 我很难找出它的含义Non Authoritative Reason HSTS 我搜索了很多 但只是想出了一些关于 HSTS 从 HTTP 重定向到 HTTPS 的解释 有人能帮我吗 顺便说一句 我正在使用 Chrome T
  • 是否可以在ajax get请求中获取页面的一部分?

    我知道我们可以在向服务器发出 GET 请求时获取整个页面 但是如果我只对该页面上的一个特定 div 感兴趣 或者更准确地说对其内容感兴趣 该怎么办 这里唯一的选择是获取整个页面 例如使用 jquery find 从中获取 div 内容吗 或
  • PHP 是否有与 Java 的 RequestDispatcher.forward 等效的功能?

    在 Java 中我可以编写一个非常基本的 JSPindex jsp像这样 这样做的效果是用户请求index jsp 或者只是包含目录 假设index jsp是目录的默认文档 将会看到home action没有浏览器重定向 即 forward
  • 为什么使用 HTTP 动词?

    因为动词的目标是像 server domain getallrecords 或 server domain delete1record 或类似的 URL 而getallrecords delete1record都是专门为特定目的而设计的 为
  • 为什么使用HTTP协议时需要指定端口号?

    即使我们使用HTTP协议 为什么还需要用IP地址指定端口号 例如 http xyz 8080 这到底是什么意思 我们已经知道 在使用 HTTP 时 请求将在端口 80 上提供服务 那么为什么我们要显式指定端口呢 HTTP 的默认端口为 80
  • asp.net core http 如果没有内容类型标头,则删除 `FromBody` 忽略

    我在 http 中使用 bodyDELETE要求 我知道目前删除主体是非标准的 但是允许的 使用时出现问题HttpClient它不允许删除请求的正文 我知道我可以使用SendAsync 但我宁愿让我的 API 更加灵活 我希望这个机构是可选
  • 按照约定应返回哪些 REST PUT/POST/DELETE 调用?

    根据 REST 意识形态 PUT POST DELETE 请求的响应正文中应该包含什么 返回码呢 是HTTP OK enough 如果有的话 这种约定的原因是什么 我发现了一篇描述 POST PUT 差异的好文章 发布与放置 http ww
  • 如何解析 Content-Disposition 标头以检索文件名属性?

    使用 go 如何解析从 http HEAD 请求检索到的 Content Disposition 标头以获取文件的文件名 此外 如何从 http HEAD 响应中检索标头本身 这样的事情正确吗 resp err http Head http
  • ASP.NET 中 HTTP 缓存相关标头的有效含义

    我正在 ASP NET 2 0 中开发一个 Web 应用程序 其中涉及通过资源处理程序 ashx 提供图像 我刚刚实现了处理缓存标头和条件 GET 请求 这样我就不必为每个请求提供所有图像 但我不确定我是否完全理解浏览器缓存发生了什么 图像
  • 404 标头 - HTTP 1.0 还是 1.1?

    为什么我能找到的几乎每个例子 包括这个问题 https stackoverflow com questions 437256 sending a 404 error in php大约一年前 说 404 标头应该是HTTP 1 0 404 N
  • $http.get() 与 JSON 数据

    我正在编写一个服务器应用程序 并希望客户端使用正文中的数据来参数化我的 GET 方法 如下所示 http v GET http localhost 3000 url text 123 foo bar GET url HTTP 1 1 Acc
  • JS 库请求的常见 HTTP 标头是什么?

    使用JavaScript 框架原型 http www prototypejs org 我注意到 Ajax 请求通过一个名为X Requested With 其他 JavaScript 库 如 jQuery dojo 和 YUI 是否会向其
  • UNIX/MacOS 上静态文件的“临时 Web 服务器”?

    是否有一个像小型网络服务器这样的东西 我可以从命令行调用它 只从本地文件系统获取文件并通过特定端口上的 HTTP 为它们提供服务 我希望能够做这样的事情 cd Sites mysite serve 10 0 1 1 8080 这应该会启动一
  • WCF WebHttp 混合身份验证(基本和匿名)

    所有这些都与 WebHttp 绑定有关 托管在自定义服务主机中 IIS 目前不是一个选项 我已经实现了自定义 UserNamePasswordValidator 和自定义 IAuthorizationPolicy 当我将端点的绑定配置为使用

随机推荐

  • linux开启启动数字小键盘,适用于使用systemd的系统

    1 创建脚本文件 usr bin numlock span class token comment bin bash span span class token keyword for span span class token funct
  • 远程连接树莓派桌面xrdp

    本文主要介绍如何通过xrdp服务远程桌面连接树莓派 xff0c 实现树莓派的远程桌面登录 xff08 1 xff09 安装tightvncserver sudo apt get install tightvncserver 1 xff08
  • archlinux安装virtualbox

    1 安装基本包 span class token function sudo span pacman S virtualbox 选择virtualbox host modules arch模块 span class token functi
  • 因修改/etc/sudoers权限导致sudo和su不能使用问题

    现象描述及问题解决 真是闲来无事手贱 xff0c 作死的节奏 xff0c 请不要问我为什么 xff0c 我也想知道为什么 为了给一个账户添加能使用 sudo的权限 xff0c 修改了 exc sudoers文件权限 修改完之后发现所有的账户
  • Qt6.2.1编译

    我用的是ubuntu20 04 ubuntu只需要按最小需要安装 xff0c 不需要安装系统更新 先更新apt get的源 cd etc apt xff0c 将source list文件内容改为阿里云源 xff1a 添加阿里源 deb ht
  • iOS Swift 运算符错误问题

    1 在Swift中 xff0c 等号两边必须空格隔开 例如下面的代码会报错 xff1a let sum 61 1 43 2 let sum 61 1 43 2 上面报如下错误 xff1a xff1d must have consistent
  • linux下普通用户执行root权限脚本

    1 安装expect yum install y expect 2 示例 a admin切换root用户脚本 span class token shebang important usr bin expect span span class
  • pve-ceph命令行安装

    用这个安装ceph成功 xff0c 如果安装报错可以多试几次 root 64 pve01 etc apt sources list d more ceph list deb http download proxmox com debian
  • 通过反射获取类和父类的属性和属性值

    通过反射我们可以获取到一个类的属性和方法 但获取父类的private的属性却不可以直接获取 需要递归调用superclass来获取属性 SuperClass java public class SuperClass private Stri
  • 利用旧电脑搭建NAS(黑群晖)

    准备工作 硬件 物品描述U盘 2个1个用来安装nas系统 xff0c 一个做成pe盘引导旧电脑启动旧电脑1个用来搭建nas任意可用电脑1个用户调试nas 软件 名称描述芯片无忧查询u盘的PID VIDOSFMount用于引导img映像文件W
  • vue3-elementPlus 大合集

    elementPlus 的 导入 第一步 安装 也可以直接 cdn 导入 npm install element span class token operator span plus span class token operator s
  • Debian用apt-get 安装软件时出现的问题!

    本想安装个搜狗输入法 xff0c 用dpkg命令安装的 xff0c 但这种安装方式不会自动安装依赖 xff0c 结果不仅没装成功 xff0c 以后使用apt get命令总会报下面这种缺少依赖的问题 root 64 debian apt ge
  • Flutter和Rust如何优雅的交互

    前言 文章的图片链接都是在github上 xff0c 可能需要 你懂得 xff1b 本文含有大量关键步骤配置图片 xff0c 强烈建议在合适环境下阅读 Flutter直接调用C层还是蛮有魅力 xff0c 想想你练习C 43 43 xff0c
  • samba服务配置

    Tip xff1a 1 centos7访问win10共享目录时 xff0c 可能需要指定协议版本 xff0c 默认版本过低 可能无法访问 xff1b 参考链接 xff1a http www mamicode com info detail
  • 阿里云网站备案-注销备案的办法

    当我们因为各种原因要注销备案时 xff0c 可能会遇到以下这些问题 那么老魏汇总了相关答案 xff0c 并且列出来给大家参考用 1 注销主体与注销网站的区别 网站备案分成两部分 xff0c 一部分是备案主体 xff08 个人或企事业单位 x
  • nodeJs(多行数据删除)

    nodeJs 多行数据删除 由于要删除多行数据 xff0c 前台就会要传多条数据到后台 xff1b 1 ajax多次发送数据到后台 xff1f 1 一般不会用这种方法 xff0c 我们要避免ajax与后台交互的次数 2 数组的传送 xff1
  • 【洛谷】P1593 因子和

    洛谷P1593 因子和 题目描述 输入两个整数 a 和 b xff0c 求 a b a b a b 的因子和 由于结果太大 xff0c 只要输出它对 9901取模的结果 输入格式 仅一行 xff0c 为两个整数 a 和 b 输出格式 输出一
  • 隐式类型转换

    转换的规则 若参与运算的数据类型不同 xff0c 则先转换成同一类型 xff0c 然后进行运算 所有的浮点运算都是以双精度进行的 xff0c 即使仅含float单精度量运算的表达式 xff0c 也要先转换成double型 xff0c 再作运
  • Android Studio调式手机时提示 device supports but apk only supports armeabi-v7a

    转载来自 https blog csdn net lbj demo article details 81503078 1 核对你手机的 CPU 架构 目前的 Android 支持的架构 CPU架构描述armeabi第5代 ARM v5TE
  • 三种常见的http content-type详解

    介绍 http协议是建立在tcp ip协议之上的应用层协议 xff0c 主要包括三个部分 xff0c 状态行 xff0c 头部信息 xff0c 消息主体 对应一个http请求就是 xff1a 请求行 xff0c 请求头 xff0c 请求体