我有一个这样的网址:
http://localhost:3000/get_agencies?zipcodecity=&zipcode=30048&city=kraków&
正如您所见,城市参数等于kraków
。当我将这样的URL传递给curl时,我以某种方式以不恰当的方式接收它:
curl = curl_easy_init();
// Some code here
curl_easy_setopt(curl, CURLOPT_URL, url);
在服务器端,我得到city=kraków
。我尝试使用curl_easy_escape(curl, url, strlen(url));
,但它只是编码所有内容。那么如何只解析查询字符串的参数值呢?
答案 0 :(得分:1)
这就是为什么我们有curl_easy_escape。
char *escaped_string=curl_easy_escape(ch,"kraków",0);
(但是,当字符串在编译时已知时,可以对编码版本进行硬编码,而不是在运行时对其进行编码,在这种情况下,硬编码版本为krak%C3%B3w
- 您的可以使用浏览器的javascript控制台来解决这个问题,只需编写encodeURIComponent("kraków");
即可查看urlencoded版本的内容。
陷阱:
当第3个参数为0时,curl使用strlen()来确定大小。这在使用utf8文本时是安全的,但对二进制数据不安全。如果你要编码二进制数据,请确保手动指定长度,因为strlen()一旦找到空字节就会停止。 (除此之外,curl_easy_escape和urlencoded数据是二进制安全的)
不要忘记curl_free(escaped_string);当你完成它时,否则你最终会发生内存泄漏。
答案 1 :(得分:1)
(抱歉,您是否对您的原始问题进行了重大编辑,或者我第一次读错了,让我再试一次)
好吧,我猜你可以修复它,根据=
和&
字符猜测数据名称和值的开始和结束位置。如果&
或?
编码错误,或者遇到使用字符等效字节的unicode字符,则不是万无一失的(编辑:最后一部分可以通过切换到unicode字符串搜索功能),这还不够,但除了这2个场景之外,这样的事情应该有效:
std::string patchInappropriatelyEncodedURL(CURL *curl, std::string url){
size_t pos=url.find("?");
size_t pos2;
if(pos==url.npos){
return url;
}
std::string ret=url.substr(0,pos+1);
std::string tmpstr;
char *escapedstr;
url=url.substr(pos+1,url.npos);
std::string type="=";
do{
pos=url.find("=");
pos2=url.find("&");
if(pos == url.npos && pos2 == url.npos){
break;
}
if(pos<pos2){
type="=";
}else{
type="&";
pos=pos2;
}
tmpstr=url.substr(0,pos);
url=url.substr(pos+1,url.npos);
escapedstr=curl_easy_escape(curl,tmpstr.c_str(),tmpstr.length());
ret.append(escapedstr);
ret.append(type);
curl_free(escapedstr);
}while(true);
escapedstr=curl_easy_escape(curl,url.c_str(),url.length());
ret.append(escapedstr);
curl_free(escapedstr);
return ret;
}
请注意,此功能基于猜测,绝不是万无一失的。我认为猜测可以通过你的目标语言的字典或其他东西得到改善,但是你的时间可能会更好地用于修复错误,导致你在程序中首先收到格式错误的网址。
< / LI>我故意省略了错误检查,因为我很懒。 curl_easy_escape可能会失败(内存不足),当它发生时,它会返回一个nullptr。你应该在代码进入生产之前解决这个问题,我太懒了。
你应该将那些curl_free放在finally {}块中,否则你可能会遇到内存泄漏,如果字符串函数抛出异常(比如substr可能会抛出bad_alloc异常),但同样,我也会这样做。我懒得修理它。