转载:http://www.cnblogs.com/softidea/p/5745369.html
转载:https://blog.csdn.net/huanongying131/article/details/78426219
转载:https://blog.csdn.net/shaderdx/article/details/28406033
转载:https://blog.csdn.net/yamahayamede/article/details/79561119(http post 上传文件格式)
转载:https://blog.csdn.net/Ideality_hunter/article/details/82971483(示例)
转载:https://blog.csdn.net/a29562268/article/details/53932582(MFC 支持 Https 示例)
转载:http://www.cnso.org/197/3835.html
转载:https://blog.csdn.net/u010256388/article/details/68491509
1.使用场景
公司产品需要做一个关于收集程序崩溃信息的模块(BugReport),需要客户端程序在崩溃发生后将崩溃日志以及转储文件发送到后台。
2.http 格式
multipart/form-data
这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的enctype 等于 multipart/form-data。直接来看一个请求示例:
BASHPOST http://www.example.com HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="text" name:key 两个空行 title value:title ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary
开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary--
标示结束。
关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。
这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。
上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype
属性指定,默认为 application/x-www-form-urlencoded
。其实 enctype
还支持 text/plain
,不过用得非常少)。
随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。
MFC代码:
#include <iostream> #include <afxinet.h> #include <Windows.h> #include <atlbase.h> #include <shlwapi.h> #include <string> #include <vector> using namespace std; #pragma warning(disable : 4996) wstring Utf8ToUnicode(const char* szU8) { if (szU8 == NULL) return L""; if (strlen(szU8) == 0) return L""; //预转换,得到所需空间的大小; int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0); //分配空间要给' '留个空间,MultiByteToWideChar不会给' '空间 wchar_t* wszString = new wchar_t[wcsLen + 1]; //转换 ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen); //最后加上' ' wszString[wcsLen] = '