HTTP使用 multipart/form-data 上传多个字段(包括文件字节流 octet-stream)
自己用到的一个向服务器上传多个字段的实例,代码不全,仅做参考。
用的是WinINet,上传的字段中包括文件字节流
/*
PHttpRequest中自行组装body之后,HttpSendRequest中自己判断body长度时,
由于文件内容中存在 \0,所以body长度计算错误,导致上传的文件内容不正确,直接指定body的长度也不行...
PHttpRequest中未使用InternetWriteFile,
*/ int UpdateToServer2(stResumeInfo st, int& candId, CString& szUpdateTime, int& nFileSize)
{
HINTERNET hSession=;
HINTERNET hConnect=;
HINTERNET hRequest=; DWORD dwNumberOfBytesWritten=;
DWORD dwBytesSend=;
DWORD dwFlag = ; candId = ;
szUpdateTime.Empty();
hSession=InternetOpen(_T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"),
INTERNET_OPEN_TYPE_PRECONFIG, , INTERNET_INVALID_PORT_NUMBER, );
if (==hSession)
{
LOG_INFO(L"----- updateResume InternetOpen return 0 !!! GetLastError: %d------", GetLastError());
return ;
} unsigned short port_ = INTERNET_DEFAULT_HTTP_PORT;
if (CConfig::GetServerType() == ) //外网用HTTPS
{
port_ = INTERNET_DEFAULT_HTTPS_PORT;
}
hConnect=InternetConnect(hSession, CConfig::URL_HOST, port_, _T(""), _T(""), INTERNET_SERVICE_HTTP, , ); //URL_HOST不能带http://
if (==hConnect)
{
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume InternetConnect return 0 !!! GetLastError: %d------", GetLastError());
return ;
} dwFlag=INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_UI ;
if (CConfig::GetServerType() == ) //外网用HTTPS
dwFlag |= INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP ;
#ifdef UP_FILE_TO_SEVER
hRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL, HTTP_VERSION, , , dwFlag, );//old
#else
hRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL_NEW, HTTP_VERSION, , , dwFlag, );
#endif
if (==hRequest)
{
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume HttpOpenRequest return 0 !!! GetLastError: %d------", GetLastError());
return ;
} if (m_bCancel) return ; //设置Header
//TCHAR content_type[128]={0};
//_stprintf_s(content_type,TEXT("Content-Type: multipart/form-data; boundary=%s"), _T(ABOUNDARY));
CString content_type = TEXT("Content-Type: multipart/form-data; boundary=");
content_type.Append(_T(ABOUNDARY));
HttpAddRequestHeaders(hRequest,content_type,-,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); //验证cid和token
CString szAuthorization = TEXT("Authorization: ");
szAuthorization.Append(/*CA2T(s64, CP_UTF8)*/CBackstageManager::GetInstance().GetAuthorizationString());
HttpAddRequestHeaders(hRequest,szAuthorization, -,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);
szAuthorization = TEXT("Agent-Info: ");
szAuthorization.Append(CBackstageManager::GetInstance().GetAgentInfo());
HttpAddRequestHeaders(hRequest,szAuthorization, -,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); #ifdef UP_FILE_TO_SEVER
//读取文件内容和长度
HANDLE hFile;
hFile=CreateFile(st.strFilePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, ,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, );
DWORD dwFileSize=GetFileSize(hFile,);
BYTE* lpBuffer=(BYTE*)VirtualAlloc(,dwFileSize,MEM_COMMIT,PAGE_READWRITE);
if (==lpBuffer)
{
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume VirtualAlloc return 0 !!! GetLastError: %d------", GetLastError());
return ;
}
DWORD dwRead;
ReadFile(hFile,lpBuffer,dwFileSize,&dwRead,);
CloseHandle(hFile);
#endif char first_boundary[]={};
char delimiter[]={};
char end_boundary[]={};
sprintf_s(first_boundary,"--%s\r\n",ABOUNDARY);
sprintf_s(delimiter,"\r\n--%s\r\n",ABOUNDARY);
sprintf_s(end_boundary,"\r\n--%s--\r\n",ABOUNDARY); //LPSTR rn="\r\n"; //HTTP POST数据中的换行必须使用\r\n
std::map<std::string, std::string> ssmap;
GetResumeInfoMap(st, ssmap); ////上传给后台必须使用字符串,不能用整型 //计算body长度
char content_dispos[]={};
std::map<std::string, std::string>::iterator it = ssmap.begin();
int length = strlen(first_boundary);
for(; it != ssmap.end(); it++)
{
memset(content_dispos, , sizeof(content_dispos));
sprintf_s(content_dispos,"Content-Disposition: form-data; name=\"%s\"\r\n\r\n", it->first.c_str());
length += strlen(content_dispos);
length += it->second.length();
length += strlen(delimiter);
} #ifdef UP_FILE_TO_SEVER
char content_dispos2[]={};
CString stmName = st.file_name;
if(stmName.GetLength() > )
{
stmName = stmName.Left() + PathFindExtension(stmName); //防止content_dispos2越界
}
std::string name = CT2A(stmName, CP_UTF8);
sprintf_s(content_dispos2, "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n", name.c_str());
LPSTR content_type2="Content-Type: application/octet-stream\r\n\r\n"; //加上File长度
length +=dwFileSize + strlen(content_dispos2) +strlen(content_type2);
#else
length -= strlen(delimiter);
#endif
length += strlen(end_boundary); if (m_bCancel) return FALSE;
INTERNET_BUFFERS BufferIn;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
BufferIn.Next = NULL;
BufferIn.lpcszHeader = NULL;
BufferIn.dwHeadersLength = ;
BufferIn.dwHeadersTotal = ;
BufferIn.lpvBuffer = NULL;
BufferIn.dwBufferLength = ;
BufferIn.dwBufferTotal = length;
BufferIn.dwOffsetLow = ;
BufferIn.dwOffsetHigh = ; if (!HttpSendRequestEx(hRequest,&BufferIn,,,))
{
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume HttpSendRequestEx return 0 !!! GetLastError: %d------", GetLastError());
return ;
} //上传body
InternetWriteFile(hRequest,(byte*)first_boundary,strlen(first_boundary),&dwNumberOfBytesWritten); //first boundary
int count = ssmap.size();
std::map<std::string, std::string>::iterator iter = ssmap.begin();
for(int index = ; iter != ssmap.end(); iter++, index++)
{
memset(content_dispos, , sizeof(content_dispos));
sprintf_s(content_dispos,"Content-Disposition: form-data; name=\"%s\"\r\n\r\n", iter->first.c_str());
InternetWriteFile(hRequest,(byte*)content_dispos, strlen(content_dispos),&dwNumberOfBytesWritten); std::string value = iter->second;
InternetWriteFile(hRequest,(byte*)value.c_str(), value.length(), &dwNumberOfBytesWritten); #ifndef UP_FILE_TO_SEVER
if(index != (count-))
#endif
InternetWriteFile(hRequest,(byte*)delimiter,strlen(delimiter),&dwNumberOfBytesWritten);
} if (m_bCancel) return ; #ifdef UP_FILE_TO_SEVER
//上传文件
InternetWriteFile(hRequest,(byte*)content_dispos2,strlen(content_dispos2),&dwNumberOfBytesWritten);
InternetWriteFile(hRequest,(byte*)content_type2,strlen(content_type2),&dwNumberOfBytesWritten);
InternetWriteFile(hRequest,lpBuffer,dwFileSize,&dwNumberOfBytesWritten);
#endif //last boundary
InternetWriteFile(hRequest,(byte*)end_boundary,strlen(end_boundary),&dwNumberOfBytesWritten); if(!HttpEndRequest(hRequest,,,))
{
int a = GetLastError();
HttpEndRequest(hRequest,,,);
} #ifdef UP_FILE_TO_SEVER
VirtualFree(lpBuffer,,MEM_RELEASE);
#endif
if (m_bCancel) return ;
//获取返回数据
std::stringstream sstream;
GetResponse(&sstream, hRequest, );
Json::Value root;
Json::Reader reader;
reader.parse(sstream.str(), root);
int code = -;
if(!root["code"].isNull())
{
code = root["code"].asInt(); //0表示成功,
}if(!root["data"].isNull())
{
Json::Value data = root["data"];
int userId = data["userId"].asInt();
candId = data["candId"].asInt();
int resumeId = data["resId"].asInt();
nFileSize = data["resSize"].asInt();
} InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
return ;
}
HTTP使用 multipart/form-data 上传多个字段(包括文件字节流 octet-stream)的更多相关文章
- django Form组件 上传文件
上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...
- 前端 - jquery方式 / iframe +form 方式 上传文件
环境与上一章一样 jquery 方式上传文件: HTML代码 {#html代码开始#} <input type="file" id="img" > ...
- 笔谈HTTP Multipart POST请求上传文件
公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下.以前做项目只用过get.post,对于现在这个跟服务器交互的表单请求我 ...
- 解决python发送multipart/form-data请求上传文件的问题
服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...
- python中使用multipart/form-data请求上传文件
最近测试的接口是上传文件的接口,上传单个文件,我主要使用了2种方法~ 接口例如: URL: http://www.baidu.com/*** method:post 参数: { "salar ...
- Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法
Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法 在使用struts2的项目中上传文件的时候出现了一个这样的错误: 2011-7 ...
- 使用python或robotframework调multipart/form-data接口上传文件
这几天调一个multipart/form-data类型的接口,遇到点小阻碍.之前同事有使用urllib库写了个类似的方法实现,比较长,想要改的时候发现不太好使.在网上查找发现用requests库做这个 ...
- 表单多文件上传样式美化 && 支持选中文件后删除相关项
开发中会经常涉及到文件上传的需求,根据业务不同的需求,有不同的文件上传情况. 有简单的单文件上传,有多文件上传,因浏览器原生的文件上传样式及功能的支持度不算太高,很多时候我们会对样式进行美化,对功能进 ...
- PHP文件上传设置和处理(多文件)
<!--upload.php文件内容--><?phpheader("Content-Type:text/html;charset=utf-8");/* //原来$ ...
随机推荐
- Android实践项目汇报总结(上)修改
微博客户端的设计与实现(上) 第一章 绪论 1.1课题背景 微博可以说是时下最受人们所喜爱的一种社交方式,它是一种通过关注机制分享简短实时信息的广播式的社交网络平台.通过微博我们可以了解最新的时事新闻 ...
- SPOJ Prime or Not - 快速乘 - 快速幂
Given the number, you are to answer the question: "Is it prime?" Solutions to this problem ...
- linux下保存下位机输出的串口信息为文件
linux下保存下位机输出的串口信息为文件 1.stty -F /dev/ttyUSB0 raw (转换成raw模式) 2.stty -F /dev/ttyUSB0 speed 115200 (设置波 ...
- win10 字体渲染优化 色彩调整
最近烧包买了个2k显示器,发现跟win10使用,一堆问题,最大的就是字体,其实应该买4k,那样正好设置200%字体,现在设置的124% 字体: 以前使用的是mactype这个软件 https://pa ...
- TeeChart的坐标轴
TeeChart一共有六个坐标轴,一下是默认值 tChart1.Axes.Bottom.Visible = true;//横轴 tChart1.Axes.Left.Visible = true;//纵 ...
- 【复制虚拟机】虚拟机复制后无ip的问题
先编辑虚拟机选项,把网络适配器删掉后保存,再重新添加网络适配器 然后开机 编辑文件/etc/udev/rules.d/70-persistent-net.rules,进去之后是这个样子 把前两个删掉, ...
- 51nod 1080 两个数的平方和
没心情写数学题啦啊 好难啊 #include<bits/stdc++.h> using namespace std; set<int> s; set<int>: ...
- v-bind绑定属性样式
一.class的四种绑定方式 1.布尔值的绑定方式 <div id="demo"> <span v-bind:class="{'class-a':isA ...
- Ubuntu 上 执行命令 java -version 显示 没有那个文件或目录
解决方法 执行 which java 发现默认java目录:/usr/bin/java . 查看 JAVA_HOME 路径:$JAVA_HOME,得到 /usr/local/java/jdk1.7.0 ...
- ns-3 NetAnim遇到了一个问题
安装好了 NetAnim 之后,使用NS3原有例子 third.cc ,在 Simulator::run() 前面添加如下语句: AnimationInterface anim("third ...