如何使用multipart/form-data格式上传文件

作者&投稿:龚钟 (若有异议请与网页底部的电邮联系)
如何使用multipart/form-data格式上传文件~

在网络编程过程中需要向服务器上传文件。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协议中,用 “
” 换行,而不是 “
”。
下面的代码片断演示如何构造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"
Content-Disposition: form-data; name=\"pic\"; filename=";
strMultipartFirst += L"\"" + strPhotoPath + L"\"";
strMultipartFirst += L"
Content-Type: image/jpeg

";
//
// "std::wstring strTextContent" is the text to uploaded.
//
//
// uploaded text form-part begin.
//
std::wstring strMultipartInter(L"
--");
strMultipartInter += strBoundary;
strMultipartInter += L"
Content-Disposition: form-data; name=\"status\"

";
std::wstring wstrPostDataUrlEncode(CEncodeTool::Encode_Url(strTextContent));
// add text content to send.
strMultipartInter += wstrPostDataUrlEncode;
std::wstring strMultipartEnd(L"
--");
strMultipartEnd += strBoundary;
strMultipartEnd += L"--
";
//
// 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)

enctype就是encodetype就是编码类型的意思。
multipart/form-data是指表单数据有多部分构成,既有文本数据,又有文件等二进制数据的意思。
需要注意的是:默认情况下,enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据。
application/x-www-form-urlencoded不是不能上传文件,是只能上传文本格式的文件,multipart/form-data是将文件以二进制的形式上传,这样可以实现多种类型的文件上传。

扩展资料:一、关于HTML 标签的 enctype 属性
application/x-www-form-urlencoded:在发送前编码所有字符(默认)
multipart/form-data: 不对字符编码,或在使用包含文件上传控件的表单时,必须使用该值。
text/plain:空格转换为 "+" 加号,但不对特殊字符编码。
二、enctype:规定了form表单在发送到服务器时候编码方式,有如下的三个值。
1、application/x-www-form-urlencoded。默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
2、multipart/form-data 。 指定传输数据为二进制类型,比如图片、mp3、文件。
3、text/plain。纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。

在网络编程过程中需要向服务器上传文件。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协议中,用 “
” 换行,而不是 “
”。

下面的代码片断演示如何构造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"
Content-Disposition: form-data; name=\"pic\"; filename=";

strMultipartFirst += L"\"" + strPhotoPath + L"\"";

strMultipartFirst += L"
Content-Type: image/jpeg

";

//

// "std::wstring strTextContent" is the text to uploaded.

//

//

// uploaded text form-part begin.

//

std::wstring strMultipartInter(L"
--");

strMultipartInter += strBoundary;

strMultipartInter += L"
Content-Disposition: form-data; name=\"status\"

";

std::wstring wstrPostDataUrlEncode(CEncodeTool::Encode_Url(strTextContent));

// add text content to send.

strMultipartInter += wstrPostDataUrlEncode;

std::wstring strMultipartEnd(L"
--");

strMultipartEnd += strBoundary;

strMultipartEnd += L"--
";

//

// 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是上传文件的一种方式。
Multipart/form-data其实就是浏览器用表单上传文件的方式。最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。

表单形式上传附件
具体的步骤是怎样的呢?
首先,客户端和服务器建立连接(TCP协议)。
第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。
第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。

Multipart/form-data格式就是浏览器用表单提交数据的格式
你的采纳是我前进的动力,还有不懂的地方,请你继续“追问”!
如你还有别的问题,可另外向我求助;答题不易,互相理解,互相帮助!

首先,客户端和服务器建立连接(TCP协议)。
第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。
第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。


...实现四则运算。提示:1)由用户输入两个数和运算数;2)使用异常...
include <stdlib.h> include <string.h> include <windows.h> include <math.h> include <conio.h> typedef unsigned char bool_t;enum bool_value { PAL_FALSE = 0,PAL_TRUE };enum operate_value { PLUS = 0,MINUS,MULTIP,DIVIDE };char* opr_str[] = {"+", "-", "*", "\/" ...

利用词缀词根背单词
7)表示"许多,复,多数” multi-, mult-, multipmetre (万用表) poly-, polysyllable, 8)表示“半,一半” hemi-, hemisphere demi-, demiofficial semi-, semiconductor, semitransparent pene-, pen-, peninsula 12. 表示特殊意义的前缀 1)arch-, 表示“首位,第一的,主要的”architect, archbishop 2)auto-...

gjf是什么意思?
(1)使用G03W编辑创建输入文件。(2)使用ChemBio3D创建G03W输入文件。(3)使用GaussianView创建输入文件。(4)使用ASCII文本编辑器创建输入文件。Gaussian输入文件的主要组成部分:Link0(命令行%Section)、RouteSection(计算机执行路径)、TitleSection (标题行)、Charge&Multip(电荷与自旋态)、Molecu...

用3DS MAX5.0制作水晶樱桃
(提示:本例中模型并不重要,大家可以使用任意的模型完成制作)运行3DS MAX5.0后,在建立命令面板中单击Shapes里的Line按钮,在左视图中勾画出樱桃剖面(如图1)。选中剖面进入修改命令面板,在Selection卷展栏中单击Vertex按钮显示出剖面图的顶点。在工作视图中选中所有的顶点,单击鼠标右键,选择快捷菜单...

汽车坐垫哪种好
草席,说实话随着使用中不可避免的摩擦,草席是三者中最容易烂的。使用寿命较短。所以我个人真心不太建议选择草席。冰丝,纤维强度本身就不高。冰丝织物厚度也通常不厚实,所以使用寿命不会太长,容易刮坏。亚麻,粗纤维,强度高而耐用。质感干燥舒适,是我个人最为推荐的种类。

帕萨特B5发动机资料
前悬挂采用多连杆方式,后悬挂则使用扭力梁,有效减少扭力转向。B5标准配置包括驾驶员及前排乘客安全气囊,侧安全气囊,ABS,电子差速锁,电动车窗,电加热后视镜,FM\/AM卡带机,8扬声器和CFC空调。电动天窗,电加热座椅,5速Tiptronic变速器是选装配置。大众独有4MOTION四轮驱动技术已经在匹配V6 30气门发动机...

form 提交到服务器后用request如果获取表单中的value值啊
request.getParameter("页面中标签name属性的值");如 页面 中 名字: servlet中String username = request.getParameter("username");username 就是页面中名字输入框的所输入的值了 本回答由电脑网络分类达人 董辉推荐 举报| 答案纠错 | 评论(1) 8 3 lideyu1205 采纳率:24% 擅长: 购房置业 JAVA相关 手机使用...

gjf是什么意思
(1)使用G03W编辑创建输入文件。(2)使用ChemBio3D创建G03W输入文件。(3)使用GaussianView创建输入文件。(4)使用ASCII文本编辑器创建输入文件。Gaussian输入文件的主要组成部分:Link0(命令行%Section)、RouteSection(计算机执行路径)、TitleSection (标题行)、Charge&Multip(电荷与自旋态)、...

大丰市18194824015: cadence layout editor 里面Multipart Path 怎么用 -
大季江凯因: 在layout有比较多的总线时,用multipart Path可以方便地区分各个总线.用法跟普通的path没什么两样.由于它没有快捷键,一般是画了一个后,再复制,然后把ROD改成自己能够区分的名字.一个multipart Path还可以分成很多部分,参见说明文档.

大丰市18194824015: 如何用ajax提交multipart表单 -
大季江凯因: 想用ajax做一个图片上传的功能,以前都是直接提交form,加个 enctype="multipart/form-data"属性就地了,但是现在用到ajax,这块要怎么处理呀?<br> $(".workImgUpload_btn").click(function(){<br>if($("#work_file").val()==""){<br>alert...

大丰市18194824015: 如何使用multipart/form - data格式上传文件 -
大季江凯因:档案:留意, method 必须是 POST!!

大丰市18194824015: Linux c 如何用multipart/form - data 添加具体的数据 -
大季江凯因: application/x-www-form-urlencoded: 窗体数据被编码为名称/值对.这是标准的编码格式.multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分,上传附件用到 text/plain: 窗体数据以纯文本形式进行编码,...

大丰市18194824015: js 怎么发送multiparthttpservletrequest -
大季江凯因: 1、确认;2、确认commons-fileupload.jar和org.springframework.web.jar存在环境3、MultipartHttpServletRequestmultipartRequest=(MultipartHttpServletRequest)request;这一句会报错:...

大丰市18194824015: java 怎么把 File 类型转 MultipartFile -
大季江凯因: MultipartFile是spring的一个接口,通常我们可以在controller定义方法使用MultipartFile接收form表单提交的文件,然后将MultipartFile可以转化成一个文件.这个接口通常是用来接收上传的文件,要将文件转换成MultipartFile文件,那么实际上应该考虑的是将File转换成CommonsMultipartFile.

大丰市18194824015: 新浪接口中使用multipart/form - data编码方式 怎么设置 -
大季江凯因: 将ContentType设置成multipart/form-data 接下来再怎么弄

大丰市18194824015: 手机通用车充 迷你车载USB充电器&#47;车充怎么用 -
大季江凯因: 一般是有个能插在点烟器上取电,有一个或多个USB插口的元件,配上充电线及适配多种手机的转换插头,直接插在点烟器上连接手机就行.有的是有电压规定,有的是通用的,买的时候注意看下电压.*****推荐看看本版的精华,很全面细致的专题.*****

大丰市18194824015: 如何用ajax无刷新提交multipart/form - data表单 -
大季江凯因: 正解 form表单和地址栏传值不冲突 使用了 multipart=form-data 之后 form表单和上传的文件就用upload.form 、upload.files来读取,而不能用request.form

大丰市18194824015: 如何在ajax中设置multipart/form - data -
大季江凯因: 你要先获取表单中元素的值,然后再在获取form元素调用submit()方法提交就可以达到无刷新的效果了...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网