HTTP上传数据 :表单,二进制数据(multipart/form-data application/octet-stream boundary)...
生活随笔
收集整理的這篇文章主要介紹了
HTTP上传数据 :表单,二进制数据(multipart/form-data application/octet-stream boundary)...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用WinINet
一個較簡單的例子:上傳頭像
void CBackstageManager::UpdateAvatarThreadProc(LPVOID params) {stForThread* pSt = (stForThread* )params;HINTERNET hSession=0;HINTERNET hConnect=0;HINTERNET hRequest=0;DWORD dwNumberOfBytesWritten=0;DWORD dwBytesSend=0;DWORD dwFlag = 0;hSession=InternetOpen(_T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"),INTERNET_OPEN_TYPE_PRECONFIG, 0, INTERNET_INVALID_PORT_NUMBER, 0);if (0==hSession){SAFE_DELETE(pSt);NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_TIMEOUT,0);return ;}unsigned short port_ = INTERNET_DEFAULT_HTTP_PORT;if (CConfig::IsHttps()) //外網用HTTPS {port_ = INTERNET_DEFAULT_HTTPS_PORT;}//INTERNET_SERVICE_HTTP : HTTP HTTPShConnect=InternetConnect(hSession, CConfig::URL_HOST, port_, _T(""), _T(""), INTERNET_SERVICE_HTTP, 0, 0); //URL_HOST不能帶http:// if (0==hConnect){SAFE_DELETE(pSt);NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_TIMEOUT,0);InternetCloseHandle(hSession);return ;}dwFlag=INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_UI ;if (CConfig::IsHttps()) //外網用HTTPSdwFlag |= INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP ;hRequest=HttpOpenRequest(hConnect, _T("POST"), UPDATE_AVATAR_URL,HTTP_VERSION,0, //Referrer0, //AcceptTypes dwFlag,0);if (0==hRequest){InternetCloseHandle(hConnect);InternetCloseHandle(hSession);SAFE_DELETE(pSt);NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_TIMEOUT,0);return ;}//設置HeaderCString content_type = TEXT("Content-Type: multipart/form-data; boundary=");content_type.Append(_T(ABOUNDARY));HttpAddRequestHeaders(hRequest,content_type,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);//驗證cid和tokenCString szAuthorization = TEXT("Authorization: ");szAuthorization.Append(CBackstageManager::GetInstance().GetAuthorizationString());HttpAddRequestHeaders(hRequest,szAuthorization, -1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); szAuthorization = TEXT("Agent-Info: ");szAuthorization.Append(CBackstageManager::GetInstance().GetAgentInfo()); HttpAddRequestHeaders(hRequest,szAuthorization, -1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); //讀取文件內容和長度 HANDLE hFile;hFile=CreateFile(pSt->sTmp, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);DWORD dwFileSize=GetFileSize(hFile,0);BYTE* lpBuffer=(BYTE*)VirtualAlloc(0,dwFileSize,MEM_COMMIT,PAGE_READWRITE);if (0==lpBuffer){InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);SAFE_DELETE(pSt);NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_ERROR,0);return ;}DWORD dwRead;ReadFile(hFile,lpBuffer,dwFileSize,&dwRead,0);CloseHandle(hFile);char first_boundary[64]={0};char delimiter[64]={0};char end_boundary[64]={0};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//計算body長度char content_dispos[64]={0};int length = strlen(first_boundary);CString stmName = PathFindFileName(pSt->sTmp);char content_dispos2[256]={0};if(stmName.GetLength() > 32){stmName = stmName.Left(28) + PathFindExtension(stmName); //防止content_dispos2越界 }std::string name = CT2A(stmName, CP_UTF8);sprintf_s(content_dispos2, "Content-Disposition: form-data; name=\"image\"; 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);length += strlen(end_boundary);INTERNET_BUFFERS BufferIn;BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );BufferIn.Next = NULL; BufferIn.lpcszHeader = NULL;BufferIn.dwHeadersLength = 0;BufferIn.dwHeadersTotal = 0;BufferIn.lpvBuffer = NULL; BufferIn.dwBufferLength = 0;BufferIn.dwBufferTotal = length;BufferIn.dwOffsetLow = 0;BufferIn.dwOffsetHigh = 0;if (!HttpSendRequestEx(hRequest,&BufferIn,0,0,0)){DWORD a = GetLastError();InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);SAFE_DELETE(pSt);NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_TIMEOUT,0);return ;}//上傳bodyInternetWriteFile(hRequest,(byte*)first_boundary,strlen(first_boundary),&dwNumberOfBytesWritten); //first boundary//上傳文件InternetWriteFile(hRequest,(byte*)content_dispos2,strlen(content_dispos2),&dwNumberOfBytesWritten);InternetWriteFile(hRequest,(byte*)content_type2,strlen(content_type2),&dwNumberOfBytesWritten);InternetWriteFile(hRequest,lpBuffer,dwFileSize,&dwNumberOfBytesWritten);//last boundaryInternetWriteFile(hRequest,(byte*)end_boundary,strlen(end_boundary),&dwNumberOfBytesWritten);if(!HttpEndRequest(hRequest,0,0,0))HttpEndRequest(hRequest,0,0,0);VirtualFree(lpBuffer,0,MEM_RELEASE);//獲取返回數據 std::stringstream sstream;CParseResumeTask::GetResponse(&sstream, hRequest, 5000);Json::Value root;Json::Reader reader;reader.parse(sstream.str(), root);int code = -1;if(!root["code"].isNull()){code = root["code"].asInt(); //0表示成功, }if(!root["msg"].isNull()){std::string s = root["msg"].asString();CString sss = CA2T(s.c_str(), CP_UTF8);}CString szAvatarUrl;if(!root["data"].isNull()){szAvatarUrl = CBackstageManager::GetJsonString(root, "data");CBackstageManager::GetInstance().SetAvatarDownUrl(szAvatarUrl);}InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);if(code == 0){{CBackstageManager::GetInstance().SetAvatarLocalPath(pSt->sTmp);CSaveAccount::SaveAvatarUrl(CBackstageManager::GetInstance().GetUserId(), szAvatarUrl, pSt->sTmp);}NotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_OK,0); }else{if (code == 7 || code == 8)CBackstageManager::NotifyUnlogged(code == 8);elseNotifyManager::Instance().Notify(TaskListener::TASK_TYPE_UPDATE_AVATAR_RESULT, TaskListener::TASK_STATUS_ERROR,0);}SAFE_DELETE(pSt); }?
?
較麻煩的實例:上傳簡歷文件,及各項參數
int CParseResumeTask::UpdateToServer2(const stResumeInfo& st, int& candId, CString& szUpdateTime, int& nFileSize, int& reposedCode) {HINTERNET hSession=0;HINTERNET hConnect=0;HINTERNET hRequest=0;DWORD dwNumberOfBytesWritten=0;DWORD dwBytesSend=0;DWORD dwFlag = 0;reposedCode = 0;candId = 0;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, 0, INTERNET_INVALID_PORT_NUMBER, 0);if (0==hSession){reposedCode = -1;return 0;}unsigned short port_ = INTERNET_DEFAULT_HTTP_PORT;if (CConfig::GetServerType() == 1) //外網用HTTPS {port_ = INTERNET_DEFAULT_HTTPS_PORT;}hConnect=InternetConnect(hSession, CConfig::URL_HOST, port_, _T(""), _T(""), INTERNET_SERVICE_HTTP, 0, 0); //URL_HOST不能帶http:// if (0==hConnect){InternetCloseHandle(hSession);reposedCode = -2;return 0;}dwFlag=INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_UI ;if (CConfig::GetServerType() == 1) //外網用HTTPSdwFlag |= 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_SEVERhRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL, HTTP_VERSION, 0, 0, dwFlag, 0);//old #elsehRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL_NEW, HTTP_VERSION, 0, 0, dwFlag, 0); #endifif (0==hRequest){InternetCloseHandle(hConnect);InternetCloseHandle(hSession);reposedCode = -3;return 0;}if (m_bCancel) return 0;//設置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,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);//如果當前用戶ID與預存的用戶ID不一致(已登出,或已登錄新賬戶),不再上傳int userid = CBackstageManager::GetInstance().GetUserId();if (m_nCurUserid != userid)return 0;//驗證cid和tokenCString szAuthorization = TEXT("Authorization: ");szAuthorization.Append(/*CA2T(s64, CP_UTF8)*/CBackstageManager::GetInstance().GetAuthorizationString());HttpAddRequestHeaders(hRequest,szAuthorization, -1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); szAuthorization = TEXT("Agent-Info: ");szAuthorization.Append(CBackstageManager::GetInstance().GetAgentInfo()); HttpAddRequestHeaders(hRequest,szAuthorization, -1,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, 0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);DWORD dwFileSize=GetFileSize(hFile,0);BYTE* lpBuffer=(BYTE*)VirtualAlloc(0,dwFileSize,MEM_COMMIT,PAGE_READWRITE);if (0==lpBuffer){InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);LOG_INFO(L"----- updateResume VirtualAlloc return 0 !!! GetLastError: %d------", GetLastError());return 0;}DWORD dwRead;ReadFile(hFile,lpBuffer,dwFileSize,&dwRead,0);CloseHandle(hFile); #endifchar first_boundary[64]={0};char delimiter[64]={0};char end_boundary[64]={0};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\nstd::map<std::string, std::string> ssmap;GetResumeInfoMap(st, ssmap); ////上傳給后臺必須使用字符串,不能用整型//計算body長度char content_dispos[64]={0};std::map<std::string, std::string>::iterator it = ssmap.begin();int length = strlen(first_boundary);for(; it != ssmap.end(); it++){memset(content_dispos, 0, 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_SEVERchar content_dispos2[256]={0};CString stmName = st.file_name;if(stmName.GetLength() > 32){stmName = stmName.Left(28) + 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); #elselength -= strlen(delimiter); #endiflength += strlen(end_boundary);if (m_bCancel) return FALSE;INTERNET_BUFFERS BufferIn;BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );BufferIn.Next = NULL; BufferIn.lpcszHeader = NULL;BufferIn.dwHeadersLength = 0;BufferIn.dwHeadersTotal = 0;BufferIn.lpvBuffer = NULL; BufferIn.dwBufferLength = 0;BufferIn.dwBufferTotal = length;BufferIn.dwOffsetLow = 0;BufferIn.dwOffsetHigh = 0;if (!HttpSendRequestEx(hRequest,&BufferIn,0,0,0)){InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);reposedCode = -4;return 0;}//上傳bodyInternetWriteFile(hRequest,(byte*)first_boundary,strlen(first_boundary),&dwNumberOfBytesWritten); //first boundaryint count = ssmap.size();std::map<std::string, std::string>::iterator iter = ssmap.begin();for(int index = 0; iter != ssmap.end(); iter++, index++){memset(content_dispos, 0, 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_SEVERif(index != (count-1))#endifInternetWriteFile(hRequest,(byte*)delimiter,strlen(delimiter),&dwNumberOfBytesWritten); }if (m_bCancel) return 0;#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 boundaryInternetWriteFile(hRequest,(byte*)end_boundary,strlen(end_boundary),&dwNumberOfBytesWritten);if(!HttpEndRequest(hRequest,0,0,0)){int a = GetLastError();HttpEndRequest(hRequest,0,0,0);}#ifdef UP_FILE_TO_SEVERVirtualFree(lpBuffer,0,MEM_RELEASE); #endifif (m_bCancel) return 0;//獲取返回數據 std::stringstream sstream;GetResponse(&sstream, hRequest, 5000);Json::Value root;Json::Reader reader;reader.parse(sstream.str(), root);int code = -1;if(!root["code"].isNull()){code = root["code"].asInt(); //0表示成功, reposedCode = code;}CString sss;if(!root["msg"].isNull()){std::string s = root["msg"].asString();sss = CA2T(s.c_str(), CP_UTF8);}if(!root["data"].isNull()){Json::Value data = root["data"];int userId = data["userId"].asInt();candId = data["candidateId"].asInt();int resumeId = data["resumeId"].asInt();nFileSize = data["resumeSize"].asInt();szUpdateTime = CParseResumeTask::GetJsonString(data, "updateTime");CString szResuName = CParseResumeTask::GetJsonString(data, "resumeName"); //resumeName=51job_丁奕聰(338664425).docint resumeSize = data["resumeSize"].asInt(); //resumeSize=140155 }InternetCloseHandle(hRequest);InternetCloseHandle(hConnect);InternetCloseHandle(hSession);if (code == 3002) //此候選人已存在(但簡歷不一樣),返回UI提示是替換,還是導入? {return 2;}if(code==0 || code==3000)return 1; //3000表示之前已上傳過完全相同的簡歷,算成功.(會返回候選人ID ) LOG_ERROR(L"-----上傳數據失敗,后臺返回 code: %d,Msg:%s------", code, sss);return 0; }?
轉載于:https://www.cnblogs.com/pjl1119/p/8532193.html
總結
以上是生活随笔為你收集整理的HTTP上传数据 :表单,二进制数据(multipart/form-data application/octet-stream boundary)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: QT C++ C:\Windows\SY
- 下一篇: 支付宝VIE的罪与罚