はじめに
POSTメソッドによってHTTPリクエストを行った際,どのような形式でデータが送られるか全然分かっていないので,ちょこっとだけ生データ(?)を覗いてみました.
フォームのhtml
リクエスト送信用のhtmlはつぎのとおりです.x-www-form-url-encoded
と multipart/form-data
2とおりのエンコードタイプで確認しています.一部TemplateToolkitな表記があります.
[%
enctype = 'x-www-form-urlencoded'
#enctype = 'multipart/form-data'
%]
<form action="[% URL %]" method="post" enctype="[% enctype %]">
<input type="text" name="textbox1" value="" />
<input type="text" name="textbox2" value="" />
<input type="text" name="textbox2" value="" />
<br />
<label><input type="radio" name="radio" value="radio-1" /> radio-1</label>
<label><input type="radio" name="radio" value="radio-2" /> radio-2</label>
<label><input type="radio" name="radio" value="radio-3" /> radio-3</label>
<br />
<label><input type="checkbox" name="check1" value="1" /> check-1</label>
<label><input type="checkbox" name="check2" value="2" /> check-2</label>
<label><input type="checkbox" name="check3" value="3" /> check-3</label>
<br />
<textarea name="textarea" rows="20" cols="50"></textarea>
<br />
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="file" name="file3" />
<input type="hidden" name="hidden1" value="ヒドゥン1" />
<input type="hidden" name="hidden2" value="ヒドゥン2" />
<hr />
<input type="submit" name="submit" value="submit" />
</form> |
クエリデータ出力用コード
こんな感じで出力しました.
...
use FCGI;
my $r = FCGI::Request;
while( $r->Accept >= 0 ) {
my ( $In ) = $r->getHandles;
open my $fh, '>', '出力先';
binmode $fh;
print $fh $_ while <$in>;
close $fh;
# 今回は別にループさせなくてもよさげ
} |
クエリデータ
出力データのサンプルを,次に示します.なお,Firefox 3 からのリクエストです.
x-www-form-urlencoded
textbox1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-1&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-2&radio=radio-2&check1=1&check3=3&textarea=use+FCGI%3B%0D%
0A%0D%0Amy+%24count+%3D+0%3B%0D%0Amy+%24request+%3D+FCGI%3A%3ARequest%28%29%3B%0D%0A%0D%0Awhile%28%24request-%3EAccept%28%29+%3E%3D+0%29+%7B%0D%0A++++print%28%22Content-type%3A+text%2Fhtml%5Cr%5Cn%5Cr%
5Cn%22%2C+%2B%2B%24count%29%3B%0D%0A%7D&file1=112.jpg&file2=&file3=133.jpg&hidden1=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B31&hidden2=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B32&submit=submit |
multipart/form-data
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="textbox1"
テキスト1
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="textbox2"
テキスト2-1
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="textbox2"
テキスト2-2
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="radio"
radio-2
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="check1"
1
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="check3"
3
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="textarea"
use FCGI;
my $count = 0;
my $request = FCGI::Request();
while($request->Accept() >= 0) {
print("Content-type: text/html\r\n\r\n", ++$count);
}
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="file1"; filename="112.jpg"
Content-Type: image/jpeg
<FF>^PJFIF^@^A^B^@^@d^@d^@^@<FF>^QDucky^@^A^@^D^@^@^@<^@^@<FF>^NAdobe^@d^@^@^A<FF><84>^@^F^D^D^D^E^D^F^E^E^F ^F^E^F ^F^K^L
^K
^L^P^L^L^L^L^L^L^P^L^N^O^P^O^N^L^S^S^T^T^S^S^\^[^[^[^\^_^_^_^_^_^_^_^_^_^_^A^G^G^G
^L
^X^P^P^X^Z^U^Q^U^Z^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_^_<FF>^C^@^D^@^C^A^Q^@^B^Q^A^C^Q^A<FF><A7>^@^@^B^C^A^A^A^A^@^@^@^@^@^@^@^@^@^C^D^A^B^E
...
}X <84>%^X^D^Q<86><80>b^B
)?N!W1s^@<A0><AD>1^E^@ " P<AB><8B>U#B<A4>C:<A4>r^P<94>^B
<85>^Z`J<94>X<A0><92>|a<AC> C6
<89>!wF<F2><B7><A9>CT<AA>^Q*<A4><A2>^V<FE><B8><A2>^XY#^U-^B<84>(^D^Z^D^@,<85>@^B<96>UF<AA>LU@^E^T<A2>7<90>74J<A8><8A><85>@^@^@^K<BC>^K8^E^B~Q /$+<AD>S^.^EB<FF>
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="hidden1"
ヒドゥン1
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="hidden2"
ヒドゥン2
-----------------------------14042802788933518161505795335
Content-Disposition: form-data; name="submit"
submit
-----------------------------14042802788933518161505795335-- |
他のブラウザでも 〜x-www-form-urlencoded編〜
Safari 4
textbox1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-1&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-2&radio=radio-2&check1=1&check3=3&textarea=use+FCGI%3B%0D%
0A%0D%0Amy+%24count+%3D+0%3B%0D%0Amy+%24request+%3D+FCGI%3A%3ARequest%28%29%3B%0D%0A%0D%0Awhile%28%24request-%3EAccept%28%29+%3E%3D+0%29+%7B%0D%0A++++print%28%22Content-type%3A+text%2Fhtml%5Cr%5Cn%5Cr%
5Cn%22%2C+%2B%2B%24count%29%3B%0D%0A%7D&hidden1=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B31&hidden2=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B32&submit=submit |
IE6
textbox1=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%881&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-1&textbox2=%E3%83%86%E3%82%AD%E3%82%B9%E3%83%882-2&radio=radio-2&check1=1&check3=3&textarea=use+FCGI%3B%0D%
0A%0D%0Amy+%24count+%3D+0%3B%0D%0Amy+%24request+%3D+FCGI%3A%3ARequest%28%29%3B%0D%0A%0D%0Awhile%28%24request-%3EAccept%28%29+%3E%3D+0%29+%7B%0D%0A++++print%28%22Content-type%3A+text%2Fhtml%5Cr%5Cn%5Cr%
5Cn%22%2C+%2B%2B%24count%29%3B%0D%0A%7D%0D%0A&file1=D%3A%5CDropbox%5CMy+Dropbox%5Cneko%5C112.jpg&file2=&file3=D%3A%5CDropbox%5CMy+Dropbox%5Cneko%5C133.jpg&hidden1=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B31&
hidden2=%E3%83%92%E3%83%89%E3%82%A5%E3%83%B32&submit=submit |
他のブラウザでも 〜multipart/form-data編〜
Safari 4
...
------WebKitFormBoundary3UGfDBKUDeMM8GCY
Content-Disposition: form-data; name="check3"
3
------WebKitFormBoundary3UGfDBKUDeMM8GCY
Content-Disposition: form-data; name="textarea"
use FCGI;
my $count = 0;
my $request = FCGI::Request();
while($request->Accept() >= 0) {
print("Content-type: text/html\r\n\r\n", ++$count);
}
------WebKitFormBoundary3UGfDBKUDeMM8GCY
Content-Disposition: form-data; name="file1"; filename="112.jpg"
Content-Type: image/jpeg
<FF>^PJFIF^@^A^B^@^@d^@d^@^@<FF>^QDucky^@^A^@^D^@^@^@<^@^@<FF>^NAdobe^@d^@^@^A<FF><84>^@^F^D^D^D^E^D^F^E^E^F ^F^E^F ^F^K^L
^K
... |
IE6
...
-----------------------------7d91d42a705e6
Content-Disposition: form-data; name="check3"
3
-----------------------------7d91d42a705e6
Content-Disposition: form-data; name="textarea"
use FCGI;
my $count = 0;
my $request = FCGI::Request();
while($request->Accept() >= 0) {
print("Content-type: text/html\r\n\r\n", ++$count);
}
-----------------------------7d91d42a705e6
Content-Disposition: form-data; name="file1"; filename="D:\Dropbox\My Dropbox\neko\112.jpg"
Content-Type: image/pjpeg
<FF>^PJFIF^@^A^B^@^@d^@d^@^@<FF>^QDucky^@^A^@^D^@^@^@<^@^@<FF>^NAdobe^@d^@^@^A<FF><84>^@^F^D^D^D^E^D^F^E^E^F ^F^E^F ^F^K^L
^K
... |
まとめ
わかったことを簡単に.
x-www-form-urlencoded
- どのブラウザからでもデータ形式は同じ.
- GETリクエスト時の
QUERY_STRING
と同様の処理でよさげ?
multipart/form-data
- データの「境界」を表す行の形式が,ブラウザによってちょこっと異なる.
共通
- IE6からの送信時,「ファイル名」がフルパスとなる.
おわりに
以上,POSTリクエスト時,クエリデータがどんな形式で送られるのかをちょこっとだけ覗いてみました.
CGI
モジュールのVars
メソッドやparam
メソッドも,このデータを基に行っているんですね,きっと.一度ソースにも目を通しておきたいところです.