multiparfile上传文件怎么读取参数

multiparfile上传文件怎么读取参数,第1张

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="UPFile.WebForm2" %>

<!DOCTYPE html PUBLIC "-//W3C/饥辩/DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title></title>

</head>

<body>

<form id="form1" runat="server" method="post" enctype="multipart/form-data" action="WebForm2.aspx">

<div>

<input id="烂逗缺File1"指激 type="file" name="File1"/>

<input type="submit" />

</div>

</form>

</body>

</html>

前段时间遇到了一个很诡异的Bug,发送FormData类型数据的POST请求被浏览器把Content-Type自动设置为了application/json,导致后端无法解析出正确的数据来。在尝试解决这个问题的时候比较深入的调研了multipart/form-data类型数据的相关内容,所以有了这篇文章来记录分享一下。

一般来说,前端在进行Post请求的时候会根据场景发送不同类型的数据,该Post请求头的Content-Type字段必须声明相应的数据类型,比如说application/x-www-form-urlencoded、application/json、multipart/form-data等,根据实际应用,有时候会需要请求时来手动设置,不过大部分情况下浏览器会根据Body中的数据来自发的设置相应的请求头。

POST请求时发送FormData类型的数据会将设置multipart/form-data,完整的设置如下:

前半部分代表数据类型,而boundary代表分隔符,boundary对应的xxxx是由请求方自定义设置的。

一般来说常常在需要发送文件或者需要发送文件加文本的时候我们才会使用FromData类型的数据格式来发送,FromData格式的数据同样是通过键值对的形式来表现的,不过实际的消息缓卖格式如下

这个FormData类型的数据可以理解为有两个key,分别是foo和baz,他们的值用boundary分隔,这里就是xxxx。

一般来说,表单提交是以前最常用的一种发送方式,将 <form></form>标签中的enctype设置为 multipart/form-data 就可以发送,我们常常是在提交带有文件的表单时使用这种格式的数据。

在这种表单提交的情景下,我们不需要手动设置Content-Type,所以也不用去管Body中的数据是如何排列的,不需要知道boundary是什么,这些都有浏览器来自动完成。

现代的前端开发已经很少会用纯表单提交的方式了,表单一般只是用来获取数据,比如说用 <input type="file" />来获取文件数据,然扰扒逗后实例化一个FormData类型的对象来存储这些数据,然后通过ajax或fetch来进行http请求。

这里尤其注意的是,我们不需要设置Content-Type,因为浏览器会自动设置。如果我们手动设置了Content-type,会覆盖掉浏览器自己的设置,而因为我们不知道formData对象里面的boundary分隔符是什么,所以就会导致后端接受到数据以后在Content-type中找不到boundary或者boundary的值与formData中的boundary不一致,导致无法获取正确的数据。

这里就要提到我一开始提到的Bug了,公司自己开发的H5页面,在IOS系统的钉钉内置的浏览器中发生了这个问题。浏览器会自动把发送FormData类型的数据的Post请求的Content-Type设置为application/json,导致后端无法解析出正确的数据来。这里我尝试手动来设置请求头,但就像上文说的那样,想尽办法都拿不到formData对象里面的boundary,后来决定Body中不使用FormData格式的数据,而是直接用字符串来模拟FormData真正的存储数据的格式,如下:

模拟这种类型的字符串,然后将其放到body中发送出去,boundary同时也可以自己定义。

其中比较麻烦的一步就是File类型的数据该如何转化,这里需要使用 FileReader 来读取出File类型数据的内容来,这里独处来的数据是Buffer类型的,然后将其转化成String写进这个模此枝拟FormData的字符串中。

最后,将这个模拟FormData的字符串放到Body中然后使用Post请求发出,此时的POST请求我们就可以手动设置Content-Type,其中boundary的值我们也已经知晓了。

至于具体的实现,大家可以参考 MDN上的示例 ,这里有比较完整的源码。

说实话,自己模拟FormData类型的数据比想象中的要困难,这其中的难点主要还是在对File类型数据的处理上,如果数据比较大就必须分片来装换,否则就会超出变量的存储极限,有点大文件分片上传的意思。而且其中还遇到了png等格式的文件转换后后端依旧无法识别的现象。这篇文章主要还是记录分享一下multipart/form-data这种类型的Post请求的一些细节。

SpringMVC默认是关闭fileupload功能的,开启该能够并验旅虚证文件上传,需要做如下几件事情:

第一:打开SpringMVC的文件上传功能:

***-servlet.xml中配置:

<bean id="multipartResolver"

class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="maxUploadSize" value="100000"/>

<property name="maxInMemorySize" value="10240" />

</bean>

配置后,当SpringMVC接受到multipartRequest的时候,就会把HttpServletRequest转为MultipartHttpServletRequest类型,

第二步:创建上传文件的file.jsp:

<form action="dynamicFields.action?method=uploadFile" method="post" enctype="multipart/form-data"><input type="file" name="myfile" id="空镇汪myfile" value="" /><br/><input type="submit" value="确认提交"></form>

一定斗仔不要漏掉enctype="multipart/form-data",否则web容器认为这不是一个MultipartRequest请求,

会报错org.springframework.web.multipart.MultipartException: The current

request is not a multipart request。

第三步:Controller层创建代码:

@RequestMapping(params = {"method=uploadFile"})

public ModelAndView uploadFile(@RequestParam("myfile") MultipartFile myfile,

HttpServletRequest request, HttpServletResponse response) throws Exception {

if(!myfile.isEmpty()){

logger.info(myfile.getName())

byte[] bs= myfile.getBytes()

logger.info(new String(bs))

}

return null

}

部署web应用运行后,能够看到控制台中打印出上传文件的内容,BINGO搞定(SpringMVC依赖common-fileupload.jar,需要加载该jar包)


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12298564.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存