文字コード polyglot

IE限定。外から指定されるcharsetに応じて挙動を変えるJavaScriptの関数の実装例。以下のコードを Shift_JIS として例えば charset.js のような名前で保存する。

function detectCharSet()
{
    try{
        var ADE = 'アア';         // 0xB1 x2
        if(+ADE-0 == 10 ){
            return 'UTF-7';
        }
        if( ADE == 11 ){
            return 'US-ASCII';          // 0xB1 means 0x31
        }
        if( ADE.charCodeAt(0) == 0xFF71 ){
            return 'Shift_JIS';         // Halfwidth Katakana Letter A x2
        }
        if( ADE.charCodeAt(0) == 0x81FC ){
            return 'EUC-JP';            // 0xB1B1 is U+81FC ,kanji 'USU'
        }
        if( ADE.charCodeAt(0) == 0xFFFD ){
            return 'UTF-8';             // 0xB1B1 is invalid UTF-8
        }
        alert( /unknown/.source );
    }catch(e){
        alert(/unknown/.source);
    }
}



呼び出す側の例はこんな感じ。script要素を動的に追加したときは、onreadystatechange で追加の完了を検出できるので、そのタイミングで追加された js 内の関数を呼び出し、追加された要素そのものを削除する。

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
    function foo( src, cs )
    {
        var s = document.createElement( "script" );
        var ss;
        s.type = "text/javascript";
        s.charset= cs;
        s.language= "javascript";
        s.onreadystatechange = function(){
            if( s.readyState.match(/(complete|loaded)/) ){
                var c = detectCharSet();
                alert( c );
                if( ss ) document.getElementsByTagName("head")[0].removeChild( ss );
            }
        }
        s.src = src;
        ss = document.getElementsByTagName("head")[0].appendChild( s );
    }
</script>

</head>
<body>
    <input type="button" value=" us-ascii " onclick="javascript:foo('charset.js', 'us-ascii')">
    <input type="button" value=" utf-7 " onclick="javascript:foo('charset.js', 'utf-7')">
    <input type="button" value=" utf-8 " onclick="javascript:foo('charset.js', 'utf-8')">
    <input type="button" value="Shift_JIS" onclick="javascript:foo('charset.js', 'Shift_JIS')">
    <input type="button" value=" EUC-JP " onclick="javascript:foo('charset.js', 'EUC-JP')">
</body>
</html>