根据请求报文头header中的Content-Type 标记着传输的编码方式的不同供服务端识别,其主要分为两类:
1、 Content-Type: application/x-www-form-urlencoded
默认的MIME内容编码类型。针对post请求,有如下:
举个例子:
我们通过Jmeter的示例Paameter中添加如下参数如下:
请求的效果如下:
我们注意到,有个Body Data,这个其实和Parameter是等效的,如下:
请求的效果如下:
如果提交的方式为get,则会将上述参数加到url之后,在Jmeter中只支持Parameters形式,如下:
输出效果为:
注意:将请求的参数值经过urlencode进行编码。
2、Content-Type:
multipart/form-data;boundary=G15HTm7XFRNWoT0n5DqzbjnxVzgdrwsx
适合传输大的二进制或者文本数据
如下:
--EY3zmEHMPHNGZTOZV5fuTl-EQoCLA5kkff
Content-Disposition: form-data; name="appid"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
26
--EY3zmEHMPHNGZTOZV5fuTl-EQoCLA5kkff
Content-Disposition: form-data; name="agent"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
test
--EY3zmEHMPHNGZTOZV5fuTl-EQoCLA5kkff
Content-Disposition: form-data; name="input"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
0b53RxhdxkPO0fMUrcdVWI/6+ayAESOp0/dVATCXisV94RxEVNOPdUepAqIMWIK8gtYe/q77wR4FTPdPmx8JhdnMLLzGQMCHtCco4A
--EY3zmEHMPHNGZTOZV5fuTl-EQoCLA5kkff--
其中,--EY3zmEHMPHNGZTOZV5fuTl-EQoCLA5kkff是分隔符。
补充知识点:
php中的curl()函数进行post请求的时候,传递数据的格式可以有以下几种格式:
(1)在看PHP的post请求参数时,经常会看到将参数放入一个数组中,如下:$post_data = array(
‘name’ => ‘tim’,
‘age’ => 23,
‘sex’ => ‘boy’
);
然后,在curl中设置:curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
此时,发起的post请求的header中的Content-Type:multipart/form-data;boudary=…
这是因为,在PHP中,如果$post_data的数据类型为一维数组时,此时默认的发起请求的Content-Type为multipart/form-data。
然而,对于很多接口所谓的支持post请求,实际上只是支持post请求中的Content-Type:application/x-www-form-urlencoded。
解决办法有两种:
(1)通过http_build_query()函数,将一维数据进行urlencode相关处理转成字符串。
$post_data =http_build_query($post_data);
(2)手动构建类似$post_data = ‘name=tim&age=23&sex=boy’;(注意:这里面的key=>value 键值对的value值需要进行urlencode编码)
问题:什么是urlencode(),有什么用?比如:JMeter中的编码,这个选项要不要打钩呢?
分析:
什么是编码?
在计算机中,所有的数据在存储和运算时都要使用二进制表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储也要使用二进制来表示,而具体要用哪些二进制数字表示哪个符号,每个人都可以约定自己的额一套(这就是编码);
问题:如果post的数据中,key=value这种方式中,value中包含“?”或者“=”时如何处理,以及不同的操作系统、浏览器、不同的网页字符集(cahrset)对传值的影响
URL编码(urlencode)通常也称为百分号编码(percent-encoding)
URL只能使用 ASCII 字符集来通过英特网进行发送的。
PHP中的file_get_contents(“php://input”)的用法
在PHP中,file_get_contents()函数从整个文件中读入一个字符串。具体用法可以参见:http://www.w3school.com.cn/php/func_filesystem_file_get_contents.asp
这里,重点介绍下file_get_contents(“php://input”)的用法。
一个file_get_contents(“php://input”)的应用:
httpClient客户端请求时,设置的请求数据为json格式,服务端利用file_get_contents(“php://input”)来获取输入的数据流,由于已经知道客户端请求的数据是json,所以取得的数据$data =json_decode(file_get_contents(“php://input”)),此时,$data为json数据。(注意:$data = json_decode($originalData, true),此时,解析的数据为数组,默认不设置返回的是json对象即访问相应的值用->)。
实际栗子如下:
PHP请求函数如下:private function doHttpPost($url, $data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
发起post请求的接口:
public function httpData(){
$url = 'http://timchen529.com/home/user/test';
$post_data = array('username' => 'bob', 'key' => '123123');
$result = $this->doHttpPost($url, json_encode($post_data));
}
响应请求的接口:
public function test(){
$data =public function test(){
$data = file_get_contents("php://input");
$dataJson = json_decode($data);
Log::record('before');
Log::record('请求的数据是:'.$dataJson->username);
Log::record('after');
};
$dataJson = json_decode($data);
Log::record('before');
Log::record('请求的数据是:'.$dataJson->username);
Log::record('after');
}
注意:
上面的数据请求中,发起的http请求中body中利用json_encode设置的数据格式为json,而处理请求的数据利用json_decode来解析请求的数据,返回的是json数据。
补充知识点:file_get_contents("php://input")对于post请求中enctype=”multipart/form-data”的数据是不支持的。