一、使用 Poco::Net::HTMLForm
使用 Poco::Net::HTMLForm 获取 数据的方式如下:
virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override
{
Poco::Net::HTMLForm form(req, req.stream());
for(const auto &it : form)
{
//遍历 form 数据
std::cout << it.first << ":" << it.second << std::endl;
}
}
Poco::Net::HTMLForm 对象初始化的时候,会首先读取 req.stream() 中的数据,然后对数据进行解析。
解析过程在文件 poco/Net/src/HTMLForm.cpp 中。
从文件中可以看到,HTMLForm 只支持两种格式的数据:
- multipart/form-data
- 非multipart/form-data
44 const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
45 const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
46 const int HTMLForm::UNKNOWN_CONTENT_LENGTH = -1;
当 Poco 检测到 Content-Type 是 multipart/form-data 的时候,就会执行 void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler) 方法,如果不是 multipart/form-data ,那么就执行 void HTMLForm::readUrl(std::istream& istr) 方法。
- HTMLForm::readMultipart() 方法会把每一个 part 作为一个 name:value 进行解析;如果遇到文件 ,就直接忽略这个文件的内容。
- HTMLForm::readUrl()方法会把 content 内的所有内容作为很多 name:value 进行解析,'='作为name 和 value 的分隔符,'&'作为多个 name:value 之间的分隔符。获取name 和 value 后再进行 urldecode 解码。
Poco::Net::HTMLForm 的缺点就是把内容强制作为 form 进行解析,因为它根本不检查 Content-Type 是什么。
二、直接读取 req.stream()
如果接收到的数据是 json,那么最好不要使用 Poco::Net::HTMLForm,尤其是数据中有 '=' 存在的时候,Poco::Net::HTMLForm 会直接把 '=' 作为分隔符使用,'='左边的是 name,'='右边的是 value。
那么如何读取 json 数据呢?直接读取 req.stream(),然后再解析json数据,就像下面这样:
virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override
{
std::string data(std::istreambuf_iterator<char>(req.stream()), {});
std::cout << data << std::endl;
}
读取出来的数据存储在了 data 变量中,可以使用 Poco::JSON::Parser 进行解析:
Poco::JSON::Parser jsonParser;
object = jsonParser.parse(data).extract<Poco::JSON::Object::Ptr>();
value = object->get("name").toString();
std::cout << value << std::endl;