Shift-JIS のページから Ajax 送信しようとして文字化けしたときに… クライアントサイド (JavaScript) とサーバサイド (Java) でエンコード・デコード
古いシステムを改修していて、Shift-JIS でエンコーディングされているページから Ajax 送信する必要があり、日本語が文字化けしたので色々やったメモ。
FormData を使って、文字列だけでなく画像ファイルも一緒に送信する必要があったので、色々と制限があった。
- 画像ファイルをアップする時は POST 送信する必要がある (GET 送信は不可)。
- jQuery で Ajax 送信する際、FormData を使う場合は contentType 指定ができない (jQuery が勝手にやる)。
- processData 指定による変換を行おうとしたが、これは GET 通信のときしか設定できない。
サーバ側は Java だったので、SetEncodingFilter を突っ込めばいいか?と思ったのだが、現行の別ページのエンコーディングに影響しては困るので導入できなかった。
- 参考 : AjaxとシフトJIS - azuki note
- Ajax のリクエストのみ UTF-8 を変換しようとするサーブレットフィルタのサンプル
ちなみに FormData というのは、送信する <form>
要素を JavaScript 内で独自に構築できるようなオブジェクト。ページ内に存在する form 要素を流用して Ajax 送信するとか、ページ中に form 要素がなくとも、ゼロからフォームを作ってそれを送信したりもできる。
// こんな風に既存の form 要素を流用できる
var fd = new FormData(document.getElementById('my-form'));
// 追加したいデータがあればこうやる
// これでファイルを選択した input[type='file'] からファイルを取得して追加している
fd.append('file', $('#fileUp').prop('files')[0]);
// jQuery を使って Ajax 送信したり…。
$.ajax({
type : 'POST',
url : 'updateFile.do',
dataType : 'text',
data : fd,
processData : false,
contentType : false
}).done(function(data) {
// 受け取ったデータを処理…
});
そんなワケでどうしたかというと、
- JavaScript 側で送信する文字列を
encodeURIComponent()
を使って UTF8 ベースにエンコードしておき、 - Java 側で受け取った文字列を
URLDecoder.decode()
を使ってデコードする
という方法を取った。
/* JavaScript にて */
// 送信したい日本語を含む文字列は…
var rawFileName = $('#fileName').val();
// エンコードしておき…
var sendFileName = encodeURIComponent(rawFileName);
// FormData に追加して Ajax 送信する
fd.append('fileName', sendFileName');
/* 送信データを受け取った Java 側では */
// そのままでエンコードされた状態なので…
String fileName = form.getFileName();
// デコードして元に戻す
String decodedFileName = URLDecoder.decode(fileName, "UTF-8");
// decodedFileName が文字化けせずに文字列を受け取れている
幸い、Ajax 処理を追加しないといけないページやフォーム要素が少なかったので、こうしたエンコード・デコードを手動で愚直にやることで逃げられた。
- 参考 : escape()とencodeURI()とencodeURIComponent()の違い - Miuran Business Systems
- JavaScript の Encode 系の関数の違い
- 参考 : JavaでURLエンコード/デコードする方法と注意点 | WEB ARCH LABO
- Java のエンコード・デコード
その他参考。
- 参考 : FormData オブジェクトの利用 - ウェブデベロッパーガイド | MDN
- FormData の解説。
- 参考 : jQuery.ajax()でファイルをアップロードする方法: 小粋空間
- FormData に関する詳細。
- 参考 : 【jQuery】FormData、SerializeArrayを使用してAjaxにて簡単にFormデータを送信 | かえでBlog
- 参考 : ajaxでファイルをアップロードする方法(メモ) - Qiita
- Ajax 送信するサンプル。
- 参考 : jQuery.ajax() のリクエストパラメータを、指定した文字コードで渡す - 株式会社CFlatの明後日スタイルのブログ
- これを試してみたがうまくいかず。