Pastalablog in はてな

時代はブログ! 日記もあるよ→http://pastak-diary.hatenadiary.com

jQuery.getScriptとSJISとIEが不運にも出会ってしまった場合の話

今日ハマったので、メモ代わりに残しておきます。

(ここから下を書いてて気付いたけど、普通に文字コードの問題だから、こんな大層な条件にしなくても良かったと思ったけど、せっかく書いたので残しておきます。読むの怠くて解決策だけ知りたい人は一番下まで行って、関連記事を読みましょう。)

色々あって$.getScript()を利用していたら、初めエラーが出た時に変数がUndefinedだみたいな感じだったので、なんだこれ!?と思って原因とか探ったので書いておきました。基本はただの文字化けですが、こういうケースもあるってことで、他に同じ事例にぶつかった人向けです。

発生条件と事象について

発生条件はかなり限られていて、以下の4つを全て満たす場合に起きるエラーについて書きます。

  1. $.getScriptでjsを読み込んでいる
  2. 1.で読み込むjsがSJISで記述されている
  3. js内のコメントの行末が全角文字で終わっている
  4. Internet Explorerでアクセスしている

現象としては、コメントの終わりがエンコードの関係で正常に展開されず、IEでJavaScript実行エラーが起きます。

中身が

// コメントです
var t = 'a';
alert(t);

ã‚„

/* コメントです
*/
var t = 'a';
alert(t);

のようなSJISのjsファイルを$.getScript()で読み込むと再現されます。

回避策

前述の条件を1つでも回避すれば良いです。 やんごとなき理由がない限り、$.getScript()を使わないといけないことにはならないと思うので、素直に<script>をビューに書くか、それが無理なら、

$('<script>').attr('src','example.js').appendTo('head')

とかって書いた方が良いです。どうしてもロードしたい場合は$.ajax()を利用して、後述のサイトで紹介されている方法でxhr.overrideMimeType()に文字コードを設定してやると良いです。

原因は後述しますが、jsファイルの文字コードをUTF-8にしても解決しますし、コメントの行末を全角文字でなくしても解決します。

原因

jQueryの$.getScriptの実装部分をjQuery ver2.0.3のソースコードより引用します。

getScript: function( url, callback ) {
        return jQuery.get( url, undefined, callback, "script" );
    }

ここで呼ばれているjQuery.getはjQuery.ajaxを利用しています。

jQuery.each( [ "get", "post" ], function( i, method ) {
    jQuery[ method ] = function( url, data, callback, type ) {
        // shift arguments if data argument was omitted
        if ( jQuery.isFunction( data ) ) {
            type = type || callback;
            callback = data;
            data = undefined;
        }

        return jQuery.ajax({
            url: url,
            type: method,
            dataType: type,
            data: data,
            success: callback
        });
    };
});

$.ajaxでは読み込み先のファイルの文字コードをUTF-8として読み込んでしまうので、これが原因になっています。

意気込んでブログ記事にしたけど、本当にただの文字コードのアレで文字化けしたってだけの話だし、こんな大層にしなくてよかったなってめっちゃ後悔しています。終わり。

参考文献