① 如何使用multipart/form-data格式上传文件
在网络编程过程中需要向服务器上传文件。Multipart/form-data是上传文件的一种方式。
Multipart/form-data其实就是浏览器用表单上传文件的方式。最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。
表单形式上传附件
具体的步骤是怎样的呢?
首先,客户端和服务器建立连接(TCP协议)。
第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。
第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。
既然Multipart/form-data格式就是浏览器用表单提交数据的格式,我们就来看看文件经过浏览器编码后是什么样子。
这行指出这个请求是“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)
② 我想传一个id到处理上传文件的页面,在form表单里怎么写啊
<inputtype='hidden'name='id'value=''>//value里填要传的id值
③ form表单怎么能直接提交ftp服务器上,把文件上传到ftp服务器上!
没办法直接传的!
你只能用表单先传到web服务器上,
然后再从web服务器上传到FTP上!(可以自己写一个服务程序)
④ Java中上传文件和表单数据提交如何质莸
//1.form表单
//注:上传文件的表单,需要将form标签设置enctype="multipart/form-data"属性,意思是将Content-Type设置成multipart/form-data
<form action="xxx" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="id1" /> <br />
<input type="password" name="password" /> <br />
<input type="file" name="file" value="选择文件"/> <input id="submit_form" type="submit" value="提交"/>
</form>
//2.servlet实现文件接收的功能
boolean isMultipart = ServletFileUpload.isMultipartContent(request);//判断是否是表单文件类型
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory);
List items = sfu.parseRequest(request);//从request得到所有上传域的列表
for(Iterator iter = items.iterator();iter.hasNext();){
FileItem fileitem =(FileItem) iter.next(); if(!fileitem.isFormField()&&fileitem!=null){
//判读不是普通表单域即是file
System.out.println("name:"+fileitem.getName());
}
}
3.扩展一下springboot
@RequestMapping("/xxx")
@ResponseBody
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(new File(
file.getOriginalFilename())));
System.out.println(file.getName());
out.write(file.getBytes());
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "上传失败," + e.getMessage();
}
return "上传成功";
} else {
return "上传失败,因为文件是空的.";
}
}
⑤ 怎么在上传文件的同时提交表单
可以用“风声无组件”上传,如果还想获取除了上传文件以外的其他提交信息,只要在上传类后面读取就可以了:
以下为检验页面代码:
<!--#include file="FSUpClass.asp"-->
'--上传类函数开始--
dim upload
set upload=New UpLoadClass
upload.MaxSize = 1048000
upload.FileType = "jpg/gif/png/bmp"
'上传文件存放目录
upload.SavePath = "Upfile/"
upload.open()
if upload.Error>0 then
response.write"<SCRIPT language=JavaScript>alert('上传图片只允许gif/jpg/png/bmp格式,且不能超过1MB。');"
response.write"javascript:history.go(-1)</SCRIPT>"
end if
'--上传类函数结束--
set rs=server.createobject("adodb.recordset")
sql="select * from Table where...."
rs.open sql,conn,1,3
rs.addnew
'Pic为你上传的图片的提交名
rs("Pic")=upload.form("Pic")
'text为你提交的文本信息
rs("text")=upload.form("text")
rs....
rs.update
rs.close
⑥ html表单文件域上传有哪些事件
<input type="text" name="textfield"> 文本域
<input type="hidden" name="hiddenField"> 隐藏域
<textarea name="textarea"></textarea> 文本区
<input type="checkbox" name="checkbox" value="checkbox"> 多选
<input type="radio" name="radiobutton" value="radiobutton"> 单选
<select name="select"> 列表
</select>
<input name="imageField" type="image" src="images/arrow.gif"> 图片域
<input type="file" name="file"> 文件域
<input type="submit" name="Submit" value="提交"> 提交表单
<input type="button" name="Submit2" value="按钮"> 按钮
<input type="reset" name="Submit3" value="重置"> 重置
⑦ 怎么在form里分别上传多个文件,如图
可以用iframe上传,orm表单的method、 enctype属性必须和下面代码一样。然后将target的值设为iframe的name,这样就可以实现无刷新上传文件。
<form action="uploadfile.php" enctype="multipart/form-data" method="post" target="iframeUpload">
<iframe name="iframeUpload" src="" width="350" height="35" frameborder=0 SCROLLING="no" style="display:NONE"></iframe>
<input id="test_file" name="test_file" type="file">
<input value="上传文件" type="submit">
</form>
⑧ ajax怎么提交带文件上传表单
上传的文件是没有办法和表单内容一起异步的,可考虑使用jquery的ajaxfileupload,或是其他的插件,异步上传文件后,然后再对表单进行操作。
⑨ 如何利用curl实现form表单提交 带文件上传
//上传D盘下的test.jpg文件,文件必须存在,否则curl处理失败且没有任何提示
$data=array('name'=>'Foo','file'=>'@d:/test.jpg');
注:PHP5.5.0起,文件上传建议使用CURLFile代替@
$ch=curl_init('http://localhost/upload.php');
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
curl_exec($ch);
更多内容请参考:http://www.zjmainstay.cn/php-curl#十模拟上传文件
⑩ 支持文件上传的html表单
/可以理解为关闭符号,关闭的是input name ="myfile"type="file"
input是可以不用关闭的
tmp是 temporal 暂时的
dir是 directory 目录
都是变量名,不必纠结