IEでlocation.hrefに日本語のパラメータを付けて送信時の文字化け(UTF-8)

what

以下のコードを使いGoogle検索すると文字化けるので、なんとかしたい。


再現する環境

Windows IE6


文字化けするコード(ファイル自体の文字コードも、もちろんUTF-8
<!DOCTYPE html
    PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<script type="text/javascript">
function search_submit(){
  var q=document.search.q.value;
  location.href = "http://google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
}
</script>

<form name="search" action="http://google.com/search" method="get" onSubmit="return false">
<input type="text" name="q">
<input type="submit" onClick="search_submit()">
</form>

</body>
</html>

正しい「あいうえお」のURLエンコーディングを知る

正しい「あいうえお」のURLエンコーディングは、

%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a

です。でも今は、

%E3%81%82%E3%81%84%E3%81%81E%81%88%E3%81

な訳です。


参考=>http://www.tagindex.com/tool/url.html


また、

%E3%81%82%E3%81%84%E3%81%81E%81%88%E3%81

をデコードすると

縺ゅ>縺・∴縺

になります。


「あいうえお」をエンコードしているのはだれ?

httpヘッダを見てみる
GET /search?lr=lang_ja&ie=utf-8&oe=utf-8&q=縺ゅ>縺・∴縺 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/x-shockwave-flash, */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; WWTClient2)
Host: google.com
Connection: Keep-Alive
Cookie: PREF=ID=5a2fe89a6fed2104:TB=2:TM=1218619833:LM=1219034762:S=VZ_0P93GzsCd8gWk; NID=14=KZOwnYCvYvjG8_BN4-TCO2hsWTI8ZGDW9EbMRbutJ_lVavqI_P1p6vWTkAti0ezxMQ_4ckpT4yQXsRP965hQmdL-2KjdgUJm9wrMaKH99k0TlxtWn6UCIchR4qYORpiC

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q=%E3%81%82%E3%81%84%E3%81%81E%81%88%E3%81
Content-Type: text/html; charset=UTF-8
Date: Tue, 26 Aug 2008 08:43:05 GMT
Expires: Thu, 25 Sep 2008 08:43:05 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 309

GET /search?lr=lang_ja&ie=utf-8&oe=utf-8&q=%E3%81%82%E3%81%84%E3%81%81E%81%88%E3%81 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/x-shockwave-flash, */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; WWTClient2)
Cookie: PREF=ID=5a2fe89a6fed2104:TB=2:TM=1218619833:LM=1219034762:S=VZ_0P93GzsCd8gWk; NID=14=KZOwnYCvYvjG8_BN4-TCO2hsWTI8ZGDW9EbMRbutJ_lVavqI_P1p6vWTkAti0ezxMQ_4ckpT4yQXsRP965hQmdL-2KjdgUJm9wrMaKH99k0TlxtWn6UCIchR4qYORpiC
Connection: Keep-Alive
Host: www.google.com

HTTP/1.1 200 OK
X-TR: 2
Cache-Control: private, max-age=0
Date: Tue, 26 Aug 2008 08:43:05 GMT
Expires: -1
Content-Type: text/html; charset=UTF-8
Set-Cookie: SS=Q0=44GC44GE44GBRT8_Pz8; path=/search
Server: gws
Content-length: 27820

これをみると、こちらが「縺ゅ>縺・∴縺」を渡して、Googleさんがエンコーディングしてくれているみたいですね・・・ありがとうございます・・・。

つまり、こちら側でちゃんとエンコードしたURLを渡すか、ちゃんとしたUTF-8の文字列を渡せばいいわけですね。


encodeURIComponent を使ってみた

encodeURIComponent を使ってエンコードしてみました。

<!DOCTYPE html
    PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<script type="text/javascript">
function search_submit(){
  var q=encodeURIComponent(document.search.q.value);
  location.href = "http://google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
}
</script>

<form name="search" action="http://google.com/search" method="get" onSubmit="return false">
<input type="text" name="q">
<input type="submit" onClick="search_submit()">
</form>

</body>
</html>
httpヘッダを見てみる
GET /search?lr=lang_ja&ie=utf-8&oe=utf-8&q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/x-shockwave-flash, */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; WWTClient2)
Host: google.com
Connection: Keep-Alive
Cookie: PREF=ID=5a2fe89a6fed2104:TB=2:TM=1218619833:LM=1219034762:S=VZ_0P93GzsCd8gWk; NID=14=KZOwnYCvYvjG8_BN4-TCO2hsWTI8ZGDW9EbMRbutJ_lVavqI_P1p6vWTkAti0ezxMQ_4ckpT4yQXsRP965hQmdL-2KjdgUJm9wrMaKH99k0TlxtWn6UCIchR4qYORpiC

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A
Content-Type: text/html; charset=UTF-8
Date: Tue, 26 Aug 2008 09:03:17 GMT
Expires: Thu, 25 Sep 2008 09:03:17 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 314

GET /search?lr=lang_ja&ie=utf-8&oe=utf-8&q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/x-shockwave-flash, */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; WWTClient2)
Cookie: SS=Q0=44GC44GE44GBRT8_Pz8; PREF=ID=5a2fe89a6fed2104:TB=2:TM=1218619833:LM=1219034762:S=VZ_0P93GzsCd8gWk; NID=14=KZOwnYCvYvjG8_BN4-TCO2hsWTI8ZGDW9EbMRbutJ_lVavqI_P1p6vWTkAti0ezxMQ_4ckpT4yQXsRP965hQmdL-2KjdgUJm9wrMaKH99k0TlxtWn6UCIchR4qYORpiC
Connection: Keep-Alive
Host: www.google.com

HTTP/1.1 200 OK
X-TR: 2
Cache-Control: private, max-age=0
Date: Tue, 26 Aug 2008 09:03:17 GMT
Expires: -1
Content-Type: text/html; charset=UTF-8
Set-Cookie: SS=Q0=44GC44GE44GG44GI44GK; path=/search
Server: gws
Content-length: 29649

今度は、「あいうえお」がちゃんとエンコードされたデータがGoogleさんにわたり、それをGoogleさんがそのままリダイレクトしているみたいですね。




encodeURIComponent とは何者か?

decodeURIComponent メソッド | Microsoft Docs

encodeURI メソッドはコード化された URI を返します。結果を decodeURI に渡すと、元の文字列が返されます。encodeURI メソッドでは、「:」、「/」、「;」、「?」の各文字はコード化されません。これらの文字をコード化するには encodeURIComponent を使用します。

まとめ

document.search.q.value の値が、「縺ゅ>縺・∴縺」になってしまうのを、
encodeURIComponent(document.search.q.value) とすることにより、「%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A」したわけですが、encodeURIComponent("縺ゅ>縺・∴縺")が「%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A」にならないんですよね・・・。document.search.q.value に渡されるときに何か変化が起きたのでしょうか??謎です・・・。


ということで解決

encodeURIComponent という関数を当て、javascriptエンコードしました。

<!DOCTYPE html
    PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<script type="text/javascript">
function search_submit(){
  var q=encodeURIComponent(document.search.q.value);
  location.href = "http://google.com/search?lr=lang_ja&ie=utf-8&oe=utf-8&q="+q;
}
</script>

<form name="search" action="http://google.com/search" method="get" onSubmit="return false">
<input type="text" name="q">
<input type="submit" onClick="search_submit()">
</form>

</body>
</html>