自己用到的一个向服务器上传多个字段的实例,代码不全,仅做参考。

用的是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)的更多相关文章

  1. django Form组件 上传文件

    上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...

  2. 前端 - jquery方式 / iframe +form 方式 上传文件

    环境与上一章一样 jquery 方式上传文件: HTML代码 {#html代码开始#} <input type="file" id="img" > ...

  3. 笔谈HTTP Multipart POST请求上传文件

    公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下.以前做项目只用过get.post,对于现在这个跟服务器交互的表单请求我 ...

  4. 解决python发送multipart/form-data请求上传文件的问题

    服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...

  5. python中使用multipart/form-data请求上传文件

    最近测试的接口是上传文件的接口,上传单个文件,我主要使用了2种方法~ 接口例如: URL: http://www.baidu.com/*** method:post 参数: { "salar ...

  6. Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法

    Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法 在使用struts2的项目中上传文件的时候出现了一个这样的错误: 2011-7 ...

  7. 使用python或robotframework调multipart/form-data接口上传文件

    这几天调一个multipart/form-data类型的接口,遇到点小阻碍.之前同事有使用urllib库写了个类似的方法实现,比较长,想要改的时候发现不太好使.在网上查找发现用requests库做这个 ...

  8. 表单多文件上传样式美化 && 支持选中文件后删除相关项

    开发中会经常涉及到文件上传的需求,根据业务不同的需求,有不同的文件上传情况. 有简单的单文件上传,有多文件上传,因浏览器原生的文件上传样式及功能的支持度不算太高,很多时候我们会对样式进行美化,对功能进 ...

  9. PHP文件上传设置和处理(多文件)

    <!--upload.php文件内容--><?phpheader("Content-Type:text/html;charset=utf-8");/* //原来$ ...

随机推荐

  1. 20145101《Java程序设计》第10周学习总结

    20145101<Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 计算机网络 路由器和交换机组成了核心的 ...

  2. 20145328《网络对抗技术》Final

    系内选拔赛write-up 1 信息隐藏 第一题图片藏东西,后缀名改txt,没有发现,改rar,发现压缩包内存在key.txt,解压提示存在密码,尝试使用修复,得到key.txt,打开获取flag,S ...

  3. 強化 Python 在 Vim 裡的顏色

    我習慣用 putty 連 Unix server 開 screen,再用 vim 寫 Python.這篇記錄如何改善 Python 的顏色. 啟動 256 色 terminal 首先將可用的色彩數增加 ...

  4. 写Java代码的一些小技巧

    写Java代码有三年多了,遇到过很多坑,也有一些小小的心得.特地分享出来供各位学习交流.这些技巧主要涉及谷歌Guava工具类的使用.Java 8新特性的使用.DSL风格开发.代码封装等技巧. 一.nu ...

  5. flash,sram

    flash写入的内容不会因电源关闭而失去,读取速度慢,成本较低,一般用作程序存储器或者低速数据读取的情况. sram有最快的读写速度,但电源掉落后其内容也会失去,价格昂贵,一般用作cpu的二级缓存,内 ...

  6. UNIX网络编程--简介(一)【转】

    本文转载自:http://blog.csdn.net/yusiguyuan/article/details/11760187 一.概述 a) 在编写与计算机通信的程序时,首先要确定的就是和计算机通信的 ...

  7. Linux内核同步机制--自旋锁【转】

    本文转载自:http://www.cppblog.com/aaxron/archive/2013/04/12/199386.html 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已 ...

  8. BZOJ3300: [USACO2011 Feb]Best Parenthesis 模拟

    Description Recently, the cows have been competing with strings of balanced  parentheses and compari ...

  9. Network Simulator for P4(NSP4) src内容介绍

    Structure What's NSP4? src source code introduction What's NSP4? NSP4是一个用于P4的网络仿真工具,旨在简化P4的环境部署和运行,将 ...

  10. POJ 3667 Hotel(线段树+区间合并)

    http://poj.org/problem?id=3667 题意: 有N个房间,M次操作.有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示 ...