如何使用multipart/form-data格式上传文件
发布网友
发布时间:2022-04-23 13:36
我来回答
共2个回答
懂视网
时间:2022-05-12 03:48
一、<form></form>
在进行文件提交的说明之前,我们先来回顾一下form标签。form有很多属性,在这里我仅说明以下两个属性:
1、method (enctype为‘application/x-www-form-urlencoded’的情况)
大多数情况只会用到GET和POST。
①GET:在使用GET进行表单提交时, 用户代理(浏览器)会自动按照name=value对每一个input组件进行处理(对name和value分别使用encodeURIComponent进行编码,然后使用‘=’连接编码后的键值对,多个键值对之间使用‘&’进行连接)从而产生一个查询字符串,连接在url的后面。
②POST:POST同样会生成一个和GET一样的字符串,只不过这个字符串是在http请求头中写入的,而不是加到url的后面。
两者主要区别:
GET提交数据的大小有限制,一般是2kb,而POST理论上没有限制(不过实际大小在2GB左右)。
2、enctype
上面提到,form表单的默认值为‘application/x-www-form-urlencoded’,这就是enctype的三个值的其中之一,接下来我们详细讨论一下这三个值。
①application/x-www-form-urlencode:表单提交的默认值,POST和GET对应的行为在上面已经讨论过,这里不再赘述;
②text/plain: 取这个值时,表单的值将不会进行编码,而是使用纯文本的方式提交到后台server,这个值基本没人用,因为在进行文件的提交时,不能提供对二进制数据的良好支持。
③multipart/form-data: 当enctype使用该选项时,浏览器将不会对字符进行编码,取而代之的是:以控件(input等)为单位进行分割,为每个控件加上Content-Disposition:form-data、name(input对应的name),filename(如果提交的是文件会有改字段),以及Content-Type(和上一个字段相同,提交文件时存在):文件类型(很容易伪造)。并且还会加上boundary(分隔符,不同浏览器不同,每次提交也不同)
最终这些信息会被整合到一起,编码为一条消息提交到server(二进制数据形式)。
需要注意的是:由于主要的用途是进行文件的上传,对上传的大小有一定要求,所以method只能选择为POST,若使用GET进行上传,则只会提交文件的一个假路径。
该选项是上传文件时必须使用的选项,将enctype设置为"multipart/form-data"后就可以使用<input type="file">进行文件上传了,下面是一个demo示例:
<form action="server.js" method="POST" enctype="multipart/form-data">
<input type="file" name="file0">
<input type="submit" value="upload">
</form>
除了使用form表单进行文件的提交,平常更多的是无刷新页面的ajax,下面来看看如何使用ajax无刷新提交文件!
二、FormData
FormData是ES提供的一个API,使用它可以实现ajax的文件提交:
下面来看FormData的使用方法:
var formData = new FormData(); //创建实例,可以传入form对应的DOM节点作为参数,则表单中的数据就会保存到formData实例中。
formData.append(name, value); //使用方法append,传入对应的键和值
// 其他代码
最后将form实例扔到xhr.send();中即可。
xhr.send(formData);
var xhr = new XMLHttpRequest();
//使用FormData构造函数创建一个FormData的实例
var formData = new FormData();
// formData.append('file0', oInput.value);
//注意,这里的value不是普通的表单value,而是一个file对象
formData.append('file0', oInput.files[0]);
xhr.open('POST', 'http://localhost:8080');
xhr.onload = function(){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
console.log(xhr.responseText);
}
};
//form表单的默认值为①,而FormData的默认值为multipart/form-data,所以不用画蛇添足的去修改请求头
//xhr.setRequestHeader('Content-Type', 'multipart/form-data');
xhr.send(formData);
上面有提到,传入append的值,不是普通的input的value,而是一个file对象,有关file对象的知识限于篇幅暂不讲解,有兴趣可以自行百度。
而除了这些,对文件的操作除了一般的小体积文件,更多的则是类似于视频网站对视频这种大型文件的操作,仅仅了解这些是不足以完成这些工作的。还要学习有关的API和深入理解blob对象。 大家可以自己下去学习, 有关这方面的总结我会在以后发表。
本文讲解了使用form、FormData进行的文件提交相关内容,更多相关内容请关注Gxl网。
热心网友
时间:2022-05-12 00:56
在网络编程过程中需要向服务器上传文件。Multipart/form-data是上传文件的一种方式。
Multipart/form-data其实就是浏览器用表单上传文件的方式。最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。
表单形式上传附件
具体的步骤是怎样的呢?
首先,客户端和服务器建立连接(TCP协议)。
第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。
第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。
既然Multipart/form-data格式就是浏览器用表单提交数据的格式,我们就来看看文件经过浏览器编码后是什么样子。
点击“Browse…”分别选择“unknow.gif”和“unknow1.gif”文件,点击“submit”按纽后,文件将被上传到服务器。
下面是服务器收到的数据:
服务器收到的数据
这是一个POST请求。所以数据是放在请求体内,而不是请求头内。
这行指出这个请求是“multipart/form-data”格式的,且“boundary”是 “---------------------------7db15a14291cce”这个字符串。
不难想象,“boundary”是用来隔开表单中不同部分数据的。例子中的表单就有 2 部分数据,用“boundary”隔开。“boundary”一般由系统随机产生,但也可以简单的用“-------------”来代替。
实际上,每部分数据的开头都是由"--" + boundary开始,而不是由 boundary 开始。仔细看才能发现下面的开头这段字符串实际上要比 boundary 多了个 “--”
紧接着 boundary 的是该部分数据的描述。
接下来才是数据。
“GIF”gif格式图片的文件头,可见,unknow1.gif确实是gif格式图片。
在请求的最后,则是 "--" + boundary + "--" 表明表单的结束。
需要注意的是,在html协议中,用 “\r\n” 换行,而不是 “\n”。
下面的代码片断演示如何构造multipart/form-data格式数据,并上传图片到服务器。
//---------------------------------------
// this is the demo code of using multipart/form-data to upload text and photos.
// -use WinInet APIs.
//
//
// connection handlers.
//
HRESULT hr;
HINTERNET m_hOpen;
HINTERNET m_hConnect;
HINTERNET m_hRequest;
//
// make connection.
//
...
//
// form the content.
//
std::wstring strBoundary = std::wstring(L"------------------");
std::wstring wstrHeader(L"Content-Type: multipart/form-data, boundary=");
wstrHeader += strBoundary;
HttpAddRequestHeaders(m_hRequest, wstrHeader.c_str(), DWORD(wstrHeader.size()), HTTP_ADDREQ_FLAG_ADD);
//
// "std::wstring strPhotoPath" is the name of photo to upload.
//
//
// uploaded photo form-part begin.
//
std::wstring strMultipartFirst(L"--");
strMultipartFirst += strBoundary;
strMultipartFirst += L"\r\nContent-Disposition: form-data; name=\"pic\"; filename=";
strMultipartFirst += L"\"" + strPhotoPath + L"\"";
strMultipartFirst += L"\r\nContent-Type: image/jpeg\r\n\r\n";
//
// "std::wstring strTextContent" is the text to uploaded.
//
//
// uploaded text form-part begin.
//
std::wstring strMultipartInter(L"\r\n--");
strMultipartInter += strBoundary;
strMultipartInter += L"\r\nContent-Disposition: form-data; name=\"status\"\r\n\r\n";
std::wstring wstrPostDataUrlEncode(CEncodeTool::Encode_Url(strTextContent));
// add text content to send.
strMultipartInter += wstrPostDataUrlEncode;
std::wstring strMultipartEnd(L"\r\n--");
strMultipartEnd += strBoundary;
strMultipartEnd += L"--\r\n";
//
// open photo file.
//
// ws2s(std::wstring)
// -transform "strPhotopath" from unicode to ansi.
std::ifstream *pstdofsPicInput = new std::ifstream;
pstdofsPicInput->open((ws2s(strPhotoPath)).c_str(), std::ios::binary|std::ios::in);
pstdofsPicInput->seekg(0, std::ios::end);
int nFileSize = pstdofsPicInput->tellg();
if(nPicFileLen == 0)
{
return E_ACCESSDENIED;
}
char *pchPicFileBuf = NULL;
try
{
pchPicFileBuf = new char[nPicFileLen];
}
catch(std::bad_alloc)
{
hr = E_FAIL;
}
if(FAILED(hr))
{
return hr;
}
pstdofsPicInput->seekg(0, std::ios::beg);
pstdofsPicInput->read(pchPicFileBuf, nPicFileLen);
if(pstdofsPicInput->bad())
{
pstdofsPicInput->close();
hr = E_FAIL;
}
delete pstdofsPicInput;
if(FAILED(hr))
{
return hr;
}
// Calculate the length of data to send.
std::string straMultipartFirst = CEncodeTool::ws2s(strMultipartFirst);
std::string straMultipartInter = CEncodeTool::ws2s(strMultipartInter);
std::string straMultipartEnd = CEncodeTool::ws2s(strMultipartEnd);
int cSendBufLen = straMultipartFirst.size() + nPicFileLen + straMultipartInter.size() + straMultipartEnd.size();
// Allocate the buffer to temporary store the data to send.
PCHAR pchSendBuf = new CHAR[cSendBufLen];
memcpy(pchSendBuf, straMultipartFirst.c_str(), straMultipartFirst.size());
memcpy(pchSendBuf + straMultipartFirst.size(), (const char *)pchPicFileBuf, nPicFileLen);
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen, straMultipartInter.c_str(), straMultipartInter.size());
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen + straMultipartInter.size(), straMultipartEnd.c_str(), straMultipartEnd.size());
//
// send the request data.
//
HttpSendRequest(m_hRequest, NULL, 0, (LPVOID)pchSendBuf, cSendBufLen)
如何使用multipart/form-data格式上传文件
首先,客户端和服务器建立连接(TCP协议)。第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。Multipart/form-data格式就是浏览器用表单提交数据的格式 ...
如何把doc文件转换成PDF格式?
"1.当然可以,首先要确定自己有一个pdf文档,而且确定目的是需要将pdf文档转换为word格式,然后我们将现有文档通过迅捷pdf转换器软件打开。2.通过选择PDF转换页面功能其中的PDF文件转WORD项目拖入文件。3.接着在迅捷pdf转换器下方按自己的需要是否更改文件名,然而在保存类型中选择*.doc选项。4.全部设置完成点击开始转换,确定自己设置好路径、更改文件名和保存类型即可。5.转换完成之后的word文档同样可以通过迅捷pdf转换器重新转换成一开始的pdf文档。"1.当然可以,首先要确定自己有一个pdf文档,而且确定目的是需要将pdf文档转换为word格式,然后我们将现有文档通过迅捷pdf转换器软件打开。2.通过选择PDF转换页面功能其中的PDF文件转WORD项目拖入文件。3.接着在迅捷pdf转换器下方按自己的需要是...
使用MultipartFile上传文件
在前端上传文件时,必须使用multipart/form-data格式发送数据,否则后台将无法接收到数据。具体实现如下:对于使用form表单上传文件,需在form标签中添加属性enctype="multipart/form-data"。上传多个文件时,需在form表单中加入multiple="multiple"属性。上传文件夹时,使用webkitdirectory和directory属性。在后端处...
Python 文件上传:如何使用 multipart/form-data 编码和 requests 包_百...
通过以上的方法,可以简单快捷的实现 Requests 包在 Python 3 中使用 Multipart/Form-Data 编码并上传文件。
如何使用multipart/form-data格式上传文件
注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。数据传输 格式 必须一字不差,包括最后的回车。注意:Content-Length: 226 这里的226是红色内容的总长度(包括最后的回车)注...
不会接口测试?用Postman轻松入门(七)——文件上传请求
首先,调用上传头像接口(testingedu.com.cn/mypro...),Content-Type会自动设置,只需在form-data模式下,选择File类型,输入抓包中的'file'键名,上传所需的文件即可。调用前需确保登录,可通过登录接口先登录(testingedu.com.cn/mypro...)。对于包含文本和文件的接口(如特斯汀电商的个人信息修改...
如何使用multipart/form-data格式上传文件
表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
form表单中的enctype=multipart/form-data什么意思?
1. 基本含义:`enctype`属性定义了HTML表单提交数据时的编码类型。在默认情况下,表单数据以`application/x-www-form-urlencoded`的方式编码并发送到服务器。但是,当表单中包含文件上传字段时,需要使用不同的编码方式,即`multipart/form-data`。这种编码类型允许你将表单字段和文件作为一个整体进行传输...
java怎么post请求同时发送二进制文件和json数据?
close();} 以上步骤展示了如何在Java中使用`MultipartEntity`构建包含二进制文件和JSON数据的POST请求。注意,此方法需配合HTTP服务器端正确解析multipart/form-data格式的请求体。若需进一步了解或实践,请确保安装并配置好相关Java开发环境,如IntelliJ IDEA或Eclipse等,并熟悉HTTP协议及Java网络编程。
前端| FormData 用法详解
前端 FormData 详尽使用指南FormData 是一种Ajax2.0的对象,专为通过 XMLHttpRequest 发送数据而设计,特别是用于处理文件上传,当表单类型设置为multipart/form-data时,它能模拟表单提交的格式。其主要用途在于数据的提交和处理。创建和操作方式如下:所有输入元素需设置name属性,否则无法获取值。使用 append...
前端上传文件的几种方法
第一种:经典的form和input上传。设置form的aciton为后端页面,enctype="multipart/form-data",type=‘post’<form action='http://www.ty2y.com/' enctype="multipart/form-data" type='post'><input type='file'><input type='hidden' name='userid'><input type='hidden' name='signature...