• このエントリーをはてなブックマークに追加

はじめに

ss-2009-09-05-00 on Flickr

POSTメソッドによってHTTPリクエストを行った際,どのような形式でデータが送られるか全然分かっていないので,ちょこっとだけ生データ(?)を覗いてみました.

フォームのhtml

リクエスト送信用のhtmlはつぎのとおりです.x-www-form-url-encodedmultipart/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メソッドも,このデータを基に行っているんですね,きっと.一度ソースにも目を通しておきたいところです.