: O. Yuanying

XMLHttpRequestのPOSTメソッドにおけるFirefoxとIEの挙動の違い

XMLHttpRequestオブジェクトを使えばJavaScript上からPOSTメソッドを実行できる。

しかし、先に紹介した「Cross-Browser XMLHttpRequest」はIEとFirefox(及び部分的にOpera)に対応したクロスブラウザーなXMLHttpRequestを提供するが、このPOSTメソッドにおいて微妙な挙動の違いが起きる。

これはXMLHttpRequestオブジェクトが生成するデフォルトのRequestHeaderの違いのようだ。

IEとFirefoxにおいて以下のようなコードを書いてサーバにデータをPOSTしてみた。

var req = new XMLHttpRequest();
if (req) {
  req.onreadystatechange = function(){
  alert(req.readyState+":"+req.status);
  if (req.readyState == 4 && req.status == 200) {
    alert(req.responseText);        }
};
var url = "test1.jsp";
req.open('POST', url);

req.send("name=yuanying&email=yuanying@fraction.jp");

IEのXMLHttpRequestでPOSTした場合のRequestHeaderは以下の通り。

accept: */*
accept-language: ja
referer: http://localhost:8080/web2/js/test1.jsp
accept-encoding: gzip, deflate
user-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
host: localhost:8080
content-length: 26
connection: Keep-Alive
cache-control: no-cache
cookie: JSESSIONID=C0B286CEAFA2460C61428DDAC9A3BA50

FirefoxのXMLHttpRequestでPOSTした場合のRequestHeaderは以下の通り。

host: localhost:8080
user-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.7.5) Gecko/20041108 Firefox/1.0
accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
accept-language: ja,en-us;q=0.7,en;q=0.3
accept-encoding: gzip,deflate
accept-charset: UTF-8,*
keep-alive: 300
connection: keep-alive
content-type: text/xml
content-length: 26
cookie: JSESSIONID=D01A2C741AFEAFFE34E98ADD795D3F43
pragma: no-cache
cache-control: no-cache

このようにIEとFirefoxでは生成するデフォルトのRequestHeaderの値が異なる。 そのためRequestHeaderに依存したサーバーサイドのプログラムを作成する場合にはこの違いに注意する必要がある。

IEとFirefoxの挙動の違いは以上の通りなのだが、そこで気になったのが設定されたcontent-typeの値。

JavaのServlet/jspを用いてXMLHttpRequestからPOSTされたデータを、通常のフォームからPOSTされたデータと同じように「ServletRequest#getParameter(String name)」を用いてそのままではとって来ることはできない。なぜならIEの場合はcontent-typeが設定されず、Firefoxの場合はデフォルトでtext/xmlとなっているため。

通常のフォームによる、POSTにおけるcontent-typeは「application/x-www-form-urlencoded」である。 そのためRequestHeaderのcontent-tyeの値を「application/x-www-form-urlencoded」に上書きし、 データをPOSTする必要がある。

例えば通常のフォームと同じようにXMLHttpRequestを用いてデータをPOSTしたければ、以下のようなコードを書く必要がある。

// name=yuanying&email=yuanying@fraction.jp
// というデータをサーバにPOSTしたい場合。
var req = new XMLHttpRequest();
if (req) {
  req.onreadystatechange = function(){
  alert(req.readyState+":"+req.status);
  if (req.readyState == 4 && req.status == 200) {
    alert(req.responseText);        }
};
var url = "test1.jsp";
// RequestHeaderのcontent-typeをセットする。
req.setRequestHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
req.open('POST', url);

// データのPOST。
req.send("name=yuanying&email=yuanying@fraction.jp");