jQuery.ajax() のリクエストパラメータを、指定した文字コードで渡す

 jQuery.ajax() のレスポンスを指定した文字コードで取得する系の話はその辺にごろごろ転がっていますが、逆にリクエストを指定した文字コードで行う系の話がほとんど見つからなかったので、ライブラリを作成しました。
 考え方としては、通常は UTF-8 で行われるリクエストパラメータの URI エンコード処理を、ShiftJIS や EUC-JP で行ってやればよいだけです。……とはいえ、文字列を ShiftJIS や EUC-JP に変換する部分は大変なので、ライブラリ任せにしてしまっています。

 UTF-8 から他の文字コードへの変換処理には、http://polygon-planet-log.blogspot.jp/2012/04/javascript.html の encoder.js を使用しています。下記コードの利用には、encoder.js(https://raw.github.com/polygonplanet/Unzipper.js/master/src/encoding.j...)が必要となります。
 任意の文字コードに対する URI エンコード関数を自前で登録することもできるようになっています。encoder.js を使わず、別の文字コード変換ライブラリを使う場合も、後から jQuery.ajaxCharcode.encoders に URI エンコード関数を登録してやるだけで構いません。

(function($){

$.ajaxCharcode = {
	charcode: 'auto', // 'auto' では、HTMLドキュメントの文字コードへの変換を行う
	encoders: {
		// 'utf-8', 'utf8' では、通常通り encodeURIComponent() を用いる。
		// 'none' ではURLエンコードを行わない
		// jQuery.ajaxCharcode.encodersに独自のURLエンコード処理を追加することで、任意の文字コードにも対応可能
		'none': noConvert,
	}
};

if (typeof Encoding !== 'undefined' && Encoding.urlEncode && Encoding.convert) {
	(function() {
		$.extend($.ajaxCharcode.encoders, {
			// ShiftJIS
			'shiftjis': encodeSJIS,
			'shift_jis': encodeSJIS,
			'shift-jis': encodeSJIS,
			'sjis': encodeSJIS,
			'x-sjis': encodeSJIS,
			// EUC-JP
			'euc-jp': encodeEUC_JP,
			'eucjp': encodeEUC_JP,
			// JIS
			'jis': encodeJIS
		});

		// 文字列→文字コードの配列
		function toArray(text)
		{
			var length = text.length;
			var array = new Array(length);
			for (var i = 0; i < length; ++i) array[i] = text.charCodeAt(i);
			return array;
		}

		// ShiftJIS
		function encodeSJIS(text)
		{
			return Encoding.urlEncode(Encoding.convert(toArray(text), 'SJIS', 'UNICODE'));
		}

		// JIS
		function encodeJIS(text)
		{
			return Encoding.urlEncode(Encoding.convert(toArray(text), 'JIS', 'UNICODE'));
		}

		// EUC
		function encodeEUC_JP(text)
		{
			return Encoding.urlEncode(Encoding.convert(toArray(text), 'EUCJP', 'UNICODE'));
		}
	})();
}

// デフォルトの encodeURIComponent()
var defaultEncodeURIComponent = window.encodeURIComponent;

// デフォルトの jQuery.param()
var old_param = $.param;

// 上書き版の jQuery.param()
$.param = function() 
{
	var charcode = String($.ajaxCharcode.charcode).toLowerCase();
	if (charcode === 'utf-8' || charcode === 'utf8') {
		// UTF-8指定であれば、デフォルトの encodeURIComponent() を用いてパラメータ文字列を生成
		return old_param.apply(this, arguments);
	}
	if (charcode === 'auto') {
		// auto指定であれば、HTMLドキュメントの文字コードを用いる
		charcode = String(document.charset || document.characterSet).toLowerCase();
	}

	// 指定した文字コードに対応する変換関数があるかどうかを確認
	var converter = $.ajaxCharcode.encoders[charcode];
	if (!converter) {
		return old_param.apply(this, arguments);
	}

	// 一時的に encodeURIComponent() の動作を上書き
	window.encodeURIComponent = converter;
	try {
		// 上書きされた encodeURIComponent() を用いてパラメータ文字列を生成
		return old_param.apply(this, arguments);
	}
	finally {
		// encodeURIComponent() の動作を本来のものに戻す
		window.encodeURIComponent = defaultEncodeURIComponent;
	}
};

// 変換なし
function noConvert(text)
{
	return text;
}

})(jQuery);

 やってる事は、極めて単純。
 jQuery のリクエストパラメータの生成メソッドを上書きし、グローバルな encodeURIComponent() の代わりに、指定した文字コード(デフォルトでは HTML の文字コードと同じ)用の URI エンコード処理を使うようにしてやるだけです。
 デフォルトでは jQuery.ajaxCharcode.charcode に 'auto' を設定しているため、上記スクリプトを追加するだけで全ての jQuery.ajax() の動作が HTML の文字コードで行われるようになります。通常の Ajax 通信は UTF-8 のままにしておきたい場合は、スクリプト読み込み後に jQuery.ajaxCharcode.charcode = 'utf-8'; を追加して下さい(UTF-8 以外にしたい場所の直後だけ、文字コードを指定することになります)。

 上記スクリプトは、jQuery Form の ajaxSubmit() にも有効です(ただし、multipart/form-data で POST する場合を除く)。

$('#form').on('submit', function() {
	jQuery.ajaxCharcode.charcode = 'Shift_JIS' ;
	$(this).ajaxSubmit({
	success: function(html) { ... }
	});
	jQuery.ajaxCharcode.charcode = 'auto' ;
	return false;
});