千家信息网

网络通信第二课 HTTP报文请求数据编码 application/x-www-form-urlencoded

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,1编码说明网页中的表单使用POST方法提交时,数据内容的类型是 application/x-www-form-urlencoded,这种类型会:1.字符"a"-"z","A"-"Z","0"-"9",
千家信息网最后更新 2026年11月01日网络通信第二课 HTTP报文请求数据编码 application/x-www-form-urlencoded

1编码说明

网页中的表单使用POST方法提交时,数据内容的类型是 application/x-www-form-urlencoded,这种类型会:

1.字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_"都不会被编码;

2.将空格转换为加号 (+) ;

3.将非文本内容转换成"%xy"的形式,xy是两位16进制的数值;

4.在每个 name=value 对之间放置 & 符号。

*/

  诸如字符: / & ? @ # ; $ + = 和 %也可以被使用,但是它们各有其特殊的用途,如果一个文件名包括了这些字符( / & ? @ # ; $ + = %),

这些字符和所有其他字符就应该被编码。

 编码过程非常简单,任何字符只要不是ASCII码数字,字母,或者前面提到的标点符,它们都将被转换成字节形式,每个字节都写成这种形式:

一个"%"后面跟着两位16进制的数值。空格是一个特殊情况,因为它们太平常了。它除了被编码成"%20"以外,还能编码为一个"+"。

加号(+)本身被编码为%2B。当/ # = & 和?作为名字的一部分来使用时,而不是作为URL部分之间的分隔符来使用时,它们都应该被编码。

参考

http://www.cnblogs.com/jingzhishen/p/3506339.html

2 编码实现

C++的libcurl库并没有提供一个类似C#中URLEncoder类,或者类似Java的httpclient的具体实现,,因此提供如下的案例代码

unsigned char ToHex(unsigned char x)

{

return x > 9 ? x + 55 : x + 48;

}

unsigned char FromHex(unsigned char x)

{

unsignedchar y;

if(x >= 'A' && x <= 'Z') y = x - 'A' + 10;

elseif (x >= 'a' && x <= 'z') y = x - 'a' + 10;

elseif (x >= '0' && x <= '9') y = x - '0';

elseassert(0);

returny;

}

std::string UrlEncode(conststd::string& str)

{

std::stringstrTemp = "";

size_tlength = str.length();

for(size_t i = 0; i < length; i++)

{

if(isalnum((unsigned char)str[i]) ||

(str[i]== '-') ||

(str[i]== '_') ||

(str[i]== '.') ||

(str[i]== '~'))

strTemp+= str[i];

elseif (str[i] == ' ')

strTemp+= "+";

else

{

strTemp+= '%';

strTemp+= ToHex((unsigned char)str[i] >> 4);

strTemp+= ToHex((unsigned char)str[i] % 16);

}

}

returnstrTemp;

}

std::string UrlDecode(conststd::string& str)

{

std::stringstrTemp = "";

size_tlength = str.length();

for(size_t i = 0; i < length; i++)

{

if(str[i] == '+') strTemp += ' ';

elseif (str[i] == '%')

{

assert(i+ 2 < length);

unsignedchar high = FromHex((unsigned char)str[++i]);

unsignedchar low = FromHex((unsigned char)str[++i]);

strTemp+= high * 16 + low;

}

elsestrTemp += str[i];

}

returnstrTemp;

}

3 生产环境编码

上面的代码是对=,&也进行了编码,但是在实际的生产环境中,如果请求数据中携带的是Json格式,并且数据中使用了参数=的方式,这种情况下=&不应该被编码,所以应该单独拆分进行编码,json内容进行编码,参数键值不应该被编,代码修改如下:

std::string UrlEncode(conststd::string& str)

{

std::stringstrTemp = "";

size_tlength = str.length();

for(size_t i = 0; i < length; i++)

{

if(isalnum((unsigned char)str[i]) ||

(str[i]== '-') ||

(str[i]== '_') ||

(str[i]== '.') ||

(str[i]== '~') ||

(str[i]== '&') ||

(str[i]== '='))

strTemp+= str[i];

elseif (str[i] == ' ')

strTemp+= "+";

else

{

strTemp+= '%';

strTemp+= ToHex((unsigned char)str[i] >> 4);

strTemp+= ToHex((unsigned char)str[i] % 16);

}

}

returnstrTemp;

}

std::string UrlDecode(conststd::string& str)

{

std::stringstrTemp = "";

size_tlength = str.length();

for(size_t i = 0; i < length; i++)

{

if(str[i] == '+') strTemp += ' ';

elseif (str[i] == '%')

{

assert(i+ 2 < length);

unsignedchar high = FromHex((unsigned char)str[++i]);

unsignedchar low = FromHex((unsigned char)str[++i]);

strTemp+= high * 16 + low;

}

elsestrTemp += str[i];

}

returnstrTemp;

}

4 restful接口编码

application/x-www-form-urlencoded指定了发送的POST数据,要进行URL编码,但是前面的&,=用在POST报文前面,作为参数的时候,是不需要进行编码的,可以直接跳过。例如:

loginusername=admin&loginpassword=admin¶m={JSON报文}

对于前面的两个&&都不能进行编码,否则Java后台无法正常解析出POST数据。目前JSON报文里面存在一个uri:

http://192.168.0.225:8080/kms/services/rest/dataInfoService/downloadFileid=00000001/temp001/097_5848300_10488&token=7a57a5a7ffffffffc1a0316369671314

里面存在&,如果没有进行URL编码的话,Java后台无法正常解析出报文

因此对以前的url编码函数进行了简单的处理

std::string UrlEncode(const std::string&str)

{

std::stringstrTemp = "";

size_tlength = str.length();

for(size_t i = 0; i < length; i++)

{

/*

前面的&用来对多个参数键值进行区分,不能进行编码,后面的&必须进行编码

*/

if(i < 50 && str[i] == '&')

{

strTemp+= str[i];

continue;

}

if(isalnum((unsigned char)str[i]) ||

(str[i]== '-') ||

(str[i]== '_') ||

(str[i]== '.') ||

(str[i]== '~') ||

(str[i]== '='))

strTemp+= str[i];

elseif (str[i] == ' ')

strTemp+= "+";

else

{

strTemp+= '%';

strTemp+= ToHex((unsigned char)str[i] >> 4);

strTemp+= ToHex((unsigned char)str[i] % 16);

}

}

returnstrTemp;

}

50是一个大致的数字,应该分别对json格式内容进行编码,而不是对整一个发送报文进行编码


编码 字符 报文 数据 内容 参数 代码 形式 特殊 之间 加号 后台 字节 情况 数值 数字 来使 格式 环境 空格 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司经营范围 中关村互联网 科技集团 互联网科技行业发展 互联网科技集团 互联网科技视频 深圳卡尔迅互联网科技有限公司怎么样 互联网公司会议桌创意科技软装饰 天速互联网络科技有限公司 互联网之后的科技是什么 银川新华互联网科技职业技术培训学校图片 畅思互联网科技 中国互联网有什么科技 产业互联网科技服务公司 工业互联网科技创业 互联网公司属于科技吗 唯美互联网科技 上海万顺科技互联网有限公司招聘 同城互联网络科技 互联网科技职业技能培训学校 颐高云石互联网科技 山东特亿宝互联网科技有限公司 圆梦互联网科技 北京互联网科技公司 奇酷互联网络科技 互联网金融科技平台 玖二柒互联网科技公司待遇 新兴科技互联网创新大赛颁奖典礼 开一家科技互联网公司需要多少钱 上海京穆互联网科技有限公司 小米互联网科技园入驻
0