Oct
29
更深入了解 HTTP/1.1 POST
对于HEAD和GET,已经比较了解了,但是对POST发送的请求格式特别是HTTP实体,尤其是带有文件的HTTP请求,还很不了解,于是刚刚用PHP写了一个简单的"服务器"程序,看看浏览器到底给我发了什么,代码如下:
1. server.php
很简单的一个脚本,等待8080端口的请求,输出请求内容,然后返回一个像模像样的东东。不过需要注意,用浏览器进行请求的时候需要在发送完毕以后点击停止按钮(断开连接),这个脚本才会断开连接。脚本还存在一些其他问题,比如字符0好像输出得不太对头。不过差不多够用,大致可以让我看清楚浏览器发了什么过来。代码如下:
2. client1.html
非常简单的一个表单,发送两个值给服务器,分别是a=1&b=2,我猜中了请求实体的内容,不过我以前用telnet模拟请求的时候忘了加上Content-Type,怪不得不能正确提交,不废话了,看代码和结果吧:
输出:
3. client2.html
选中一个文件名为cipher.txt的文件,包含的内容是3个字节:123
提交请求以后server.php输出是这样的:
原来浏览器是这样处理带上传文件的表单的:用随机生成的字符串作为分隔,对于每一个值,单独用一个"部分"HTTP头+HTTP实体给出一个内容,指定实体的类型和长度。
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
1. server.php
很简单的一个脚本,等待8080端口的请求,输出请求内容,然后返回一个像模像样的东东。不过需要注意,用浏览器进行请求的时候需要在发送完毕以后点击停止按钮(断开连接),这个脚本才会断开连接。脚本还存在一些其他问题,比如字符0好像输出得不太对头。不过差不多够用,大致可以让我看清楚浏览器发了什么过来。代码如下:
<?php
//监听8080端口
$sock = socket_create_listen(8080);
$i = 0; //连接计数
//给浏览器的返回内容(随手写的拉)
$answer = <<<eot
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 10
HelloHello
eot;
while($c = socket_accept($sock)){ //如果连上了
echo "---- Start Of Connection ", $i, " ----\n";
while(socket_recv($c, $a, 1, 0)){ //如果还有数据,就输出
if(!empty($a))echo $a;
}
echo "\n---- End Of Connection ", $i, " ----\n\n";
$i++;
socket_write($c, $answer); //返回一些内容
}
//关闭连接
socket_close($sock);
?>
//监听8080端口
$sock = socket_create_listen(8080);
$i = 0; //连接计数
//给浏览器的返回内容(随手写的拉)
$answer = <<<eot
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 10
HelloHello
eot;
while($c = socket_accept($sock)){ //如果连上了
echo "---- Start Of Connection ", $i, " ----\n";
while(socket_recv($c, $a, 1, 0)){ //如果还有数据,就输出
if(!empty($a))echo $a;
}
echo "\n---- End Of Connection ", $i, " ----\n\n";
$i++;
socket_write($c, $answer); //返回一些内容
}
//关闭连接
socket_close($sock);
?>
2. client1.html
非常简单的一个表单,发送两个值给服务器,分别是a=1&b=2,我猜中了请求实体的内容,不过我以前用telnet模拟请求的时候忘了加上Content-Type,怪不得不能正确提交,不废话了,看代码和结果吧:
<html><body>
<form action="http://localhost:8080" method="POST">
<input type="hidden" name="a" value="1" />
<input type="hidden" name="b" value="2" />
<input type="submit" value="submit" />
</form>
</body></html>
<form action="http://localhost:8080" method="POST">
<input type="hidden" name="a" value="1" />
<input type="hidden" name="b" value="2" />
<input type="submit" value="submit" />
</form>
</body></html>
输出:
引用
---- Start Of Connection 0 ----
POST / HTTP/1.1
Host: localhost:88
User-Agent: Mozilla/5. (X11; U; Linux i686; zh-CN; rv:1.9..3) Gecko/289251 Ubuntu/8.4 (hardy) Firefox/3..3
Accept: text/html,application/xhtml+xml,application/xml;q=.9,*/*;q=.8
Accept-Language: zh-cn,en-us;q=.7,en;q=.3
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 3
Connection: keep-alive
Referer: http://localhost/client.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
a=1&b=2
---- End Of Connection 0 ----
POST / HTTP/1.1
Host: localhost:88
User-Agent: Mozilla/5. (X11; U; Linux i686; zh-CN; rv:1.9..3) Gecko/289251 Ubuntu/8.4 (hardy) Firefox/3..3
Accept: text/html,application/xhtml+xml,application/xml;q=.9,*/*;q=.8
Accept-Language: zh-cn,en-us;q=.7,en;q=.3
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 3
Connection: keep-alive
Referer: http://localhost/client.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
a=1&b=2
---- End Of Connection 0 ----
3. client2.html
<html><body>
<form enctype="multipart/form-data" action="http://localhost:8080" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
</body></html>
<form enctype="multipart/form-data" action="http://localhost:8080" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
</body></html>
选中一个文件名为cipher.txt的文件,包含的内容是3个字节:123
提交请求以后server.php输出是这样的:
引用
---- Start Of Connection 0 ----
POST / HTTP/1.1
Host: localhost:88
User-Agent: Mozilla/5. (X11; U; Linux i686; zh-CN; rv:1.9..3) Gecko/289251 Ubuntu/8.4 (hardy) Firefox/3..3
Accept: text/html,application/xhtml+xml,application/xml;q=.9,*/*;q=.8
Accept-Language: zh-cn,en-us;q=.7,en;q=.3
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 3
Connection: keep-alive
Referer: http://localhost/client.php
Content-Type: multipart/form-data; boundary=---------------------------1345763441846476664152674
Content-Length: 347
-----------------------------1345763441846476664152674
Content-Disposition: form-data; name="MAX_FILE_SIZE"
3
-----------------------------1345763441846476664152674
Content-Disposition: form-data; name="userfile"; filename="cipher.txt"
Content-Type: text/plain
123
-----------------------------1345763441846476664152674--
---- End Of Connection 0 ----
POST / HTTP/1.1
Host: localhost:88
User-Agent: Mozilla/5. (X11; U; Linux i686; zh-CN; rv:1.9..3) Gecko/289251 Ubuntu/8.4 (hardy) Firefox/3..3
Accept: text/html,application/xhtml+xml,application/xml;q=.9,*/*;q=.8
Accept-Language: zh-cn,en-us;q=.7,en;q=.3
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 3
Connection: keep-alive
Referer: http://localhost/client.php
Content-Type: multipart/form-data; boundary=---------------------------1345763441846476664152674
Content-Length: 347
-----------------------------1345763441846476664152674
Content-Disposition: form-data; name="MAX_FILE_SIZE"
3
-----------------------------1345763441846476664152674
Content-Disposition: form-data; name="userfile"; filename="cipher.txt"
Content-Type: text/plain
123
-----------------------------1345763441846476664152674--
---- End Of Connection 0 ----
原来浏览器是这样处理带上传文件的表单的:用随机生成的字符串作为分隔,对于每一个值,单独用一个"部分"HTTP头+HTTP实体给出一个内容,指定实体的类型和长度。
欢迎扫码关注:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。