处理SIM800L模块的时间字符串之URL编码(百分号编码)
还是之前的时间格式:
20/03/15,14:05:33+32
服务器API接受POST方式提交数据。当我们提交数据时,首先设置HTTP标头的"Content-Type"参数:
AT+HTTPPARA="CONTENT","application/x-www-form-urlencoded"
然后访问服务器API:
AT+HTTPPARA="URL","http://1.1.1.1/sms"
接着设置数据长度和超时时间:
AT+HTTPDATA=23,10000
然后发送数据,假设API接受一个timestamp参数,那发送的内容应该如此:
timestamp=20/03/15,14:05:33+32 // 不带回车换行
当你兴高采烈的使用命令提交,并且收到200响应时:
AT+HTTPACTION=1
你却发现服务器并没有收到数据。。。(以上是部分提交数据流程)
这是因为:【参考来源1】
application/
x-www-form-urlencoded
: 数据被编码成以'&'
分隔的键-值对, 同时以'='
分隔键和值. 非字母或数字的字符会被 percent-encoding: 这也就是为什么这种类型不支持二进制数据(应使用multipart/form-data
代替).
当我们提交到服务器时,会把API和参数组织起来,也就是变成如下URL:
http://1.1.1.1/sms?timestamp=20/03/15,14:05:33+32
这就涉及到URL编码问题,因为上面时间参数中的 "/" "," ":" "+" 都是URI字符类型的保留字符,根据维基百科解释【参考来源2】
如果一个保留字符在特定上下文中具有特殊含义(称作"reserved purpose") , 且URI中必须使用该字符用于其它目的, 那么该字符必须百分号编码。
所以情况就很明显了,我们需要对时间字符串中的URI保留字符进行编码:
void urldecode(void) { char time[30] = "20/03/17,05:11:10-40"; int intzone, max = 6; char timestamp[max][3],c,strzone[3], result[50]; sscanf((char*) time, "%2s/%2s/%2s,%2s:%2s:%2s%c%d", timestamp[0], timestamp[1], timestamp[2], timestamp[3], timestamp[4], timestamp[5], &c, &intzone); intzone = intzone / 4; itoa(intzone, strzone, 10); memset(result, '\0', sizeof(result));
// '/' = %2F ',' = %2C ':' = %3A strcat(result,timestamp[0]); strcat(result,"%2F"); strcat(result,timestamp[1]); strcat(result,"%2F"); strcat(result,timestamp[2]); strcat(result,"%2C"); strcat(result,timestamp[3]); strcat(result,"%3A"); strcat(result,timestamp[4]); strcat(result,"%3A"); strcat(result,timestamp[5]);
// '+'是保留字符,'-'不是,所以'+'需要编码 if (c == '+') { strcat(result, "%2B"); } else if (c == '-') { strcat(result, "-"); } if (intzone > 9) { strcat(result, strzone); } else { strcat(result, "0"); strcat(result, strzone); } printf("result:%s\n", result); }
结果: result:20%2F03%2F17%2C05%3A11%3A10-10