質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • JavaScript

    17586questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • JSON

    1238questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

【JavaScript】FileReaderで読み込んだjsonが文字化けする

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 888

hota1024

score 284

前提・実現したいこと

以下のプログラムで問題が起きています。

$('#project_json').on('change',function(evt){
  $('#project_json_denger').removeClass('hide').hide();
   var files = evt.target.files;
   var file = files[0];
   if(file.type != 'application/json'){
     $('#project_json_denger').fadeIn(300);
     return;
   }

   $(this).parent().parent().parent().hide(1000);

   Loading.file();


  reader = new FileReader();
  reader.onprogress = function(e){
    Loading.file().css('width',e.loaded / e.total * 100 + '%');
    Loading.file().text('Loading file...(' + e.loaded / e.total * 100 + '%)');
  }
  reader.onload = function(){
    Loading.file().css('width','100%');
    Loading.file().text('Loaded file!(100%)');
    setTimeout(project_load,500);
    console.log(reader.result);//ここでreader.resultの日本語が文字化けしてる
  }
  reader.readAsBinaryString(file);
});
function project_load(){
  json = JSON.parse(reader.result);
  functions = [];
  Loading.project();
  var children = json.children;
  children.some(function(child,cindex,ct){
    if(child.objName){
      child.scripts.forEach(function(script,sindex,t){

        if(script[2][0][0] == "procDef") functions.push(script[2][0]);

        setTimeout(function(){
          var parcent = (sindex + 1) / t.length;
          parcent = ((cindex + 1) * parcent) / ct.length * 100;
          Loading.project().css('width',parcent + '%');
          Loading.project().text('Getting functions...('+parcent+'%)');
        },0);
      });
    }
    setTimeout(function(){
      var parcent = (cindex + 1) / ct.length * 100;
      Loading.project().css('width',parcent + '%');
      Loading.project().text('Getting functions...('+parcent+'%)');
    },0);
  });
  setTimeout(function(){
    Loading.project().text('Geted function!(100%)');
  },1);
  setTimeout(functions_output,500);
}
function functions_output(){
  Loading.functionsOutput();
  var result = '';
  functions.forEach(function(func,index,t){
    console.log(func);
    result += 'define ' + func[1] + '<br />';


    setTimeout(function(){
      Loading.functionsOutput().css('width',(index + 1) / t.length * 100 + '%');
      Loading.functionsOutput().text('Generating define blocks(' + (index + 1) / t.length * 100 + '%)');
    },0);
  });
  $('.define_blocks').html(result);
  $('#json').text(JSON.stringify(json, null, "    "));
  editor = ace.edit("editor");
  editor.setValue(JSON.stringify(json, null, "    "));
  editor.setTheme("ace/theme/monokai");
  editor.setFontSize(14);
  editor.getSession().setMode("ace/mode/json");
  editor.getSession().setUseWrapMode(true);
  editor.getSession().setTabSize(2);
  scratchblocks.renderMatching('.define_blocks');
  setTimeout(function(){
    Loading.functionsOutput().text('Generated define blocks(100%)');
  },1);
}


スパゲッティーでごめんなさい。

これで読み込んだreader.resultの日本語の部分が文字化けしてしまいます。
読み込んだファイルはutf8です。
ブラウザは'Google Chrome'です。

JSON.parse(reader.result)の後も文字化けが起きます。
JSONは仕様どおりだと思います。

{
"objName": "Stage",
"sounds": [{
"soundName": "ポップ",
"soundID": 1,
"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"sampleCount": 258,
"rate": 11025,
"format": ""
}],
"costumes": [{
"costumeName": "背景1",
"baseLayerID": 4,
"baseLayerMD5": "739b5e2a2435f6e1ec2993791b423146.png",
"bitmapResolution": 1,
"rotationCenterX": 240,
"rotationCenterY": 180
}],
"currentCostumeIndex": 0,
"penLayerMD5": "5c81a336fab8be57adc039a8a2b33ca9.png",
"penLayerID": 0,
"tempoBPM": 60,
"videoAlpha": 0.5,
"children": [{
"objName": "sprite1",
"scripts": [[65.8, 76.1, [["procDef", "test1 %n", ["number1"], [1], false]]],
[92.7, 67.55, [["procDef", "test2 %n %s", ["number1", "string1"], [1, ""], false]]],
[97,
46.4,
[["procDef", "test3 %n %s %b", ["number1", "string1", "boolean1"], [1, "", false], false]]]],
"sounds": [{
"soundName": "ニャー",
"soundID": 0,
"md5": "83c36d806dc92327b9e7049a565c6bff.wav",
"sampleCount": 18688,
"rate": 22050,
"format": ""
}],
"costumes": [{
"costumeName": "cosutume1",
"baseLayerID": 1,
"baseLayerMD5": "f9a1c175dbe2e5dee472858dd30d16bb.svg",
"bitmapResolution": 1,
"rotationCenterX": 47,
"rotationCenterY": 55
},
{
"costumeName": "cosutume2",
"baseLayerID": 2,
"baseLayerMD5": "6e8bd9ae68fdb02b7e1e3df656a75635.svg",
"bitmapResolution": 1,
"rotationCenterX": 47,
"rotationCenterY": 55
}],
"currentCostumeIndex": 1,
"scratchX": 0,
"scratchY": 0,
"scale": 1,
"direction": 90,
"rotationStyle": "normal",
"isDraggable": false,
"indexInLibrary": 1,
"visible": true,
"spriteInfo": {
}
},
{
"objName": "sprite2",
"scripts": [[36.85,
17.8,
[["procDef", "test1 %n %s %b", ["number1", "string1", "boolean1"], [1, "", false], false]]],
[76.05,
105.45,
[["procDef",
"test2 %n %n %s %s %b %b",
["number1", "number2", "string1", "string2", "boolean1", "boolean2"],
[1, 1, "", "", false, false],
false]]]],
"sounds": [{
"soundName": "ポップ",
"soundID": 1,
"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"sampleCount": 258,
"rate": 11025,
"format": ""
}],
"costumes": [{
"costumeName": "cosutume1",
"baseLayerID": 3,
"baseLayerMD5": "d36f6603ec293d2c2198d3ea05109fe0.png",
"bitmapResolution": 2,
"rotationCenterX": 0,
"rotationCenterY": 0
}],
"currentCostumeIndex": 0,
"scratchX": -17,
"scratchY": 36,
"scale": 1,
"direction": 90,
"rotationStyle": "normal",
"isDraggable": false,
"indexInLibrary": 2,
"visible": true,
"spriteInfo": {
}
}],
"info": {
"videoOn": false,
"userAgent": "Scratch 2.0 Offline Editor",
"flashVersion": "MAC 26,0,0,137",
"scriptCount": 5,
"swfVersion": "v456.0.4",
"spriteCount": 2
}
}


長くてすいません。
JavaScriptとHTMLは両方UTF8です。
<meta charset="utf-8">も書いてあります。
文字化け後のjsonは以下のとおりです。

文字化けjson

不思議とteratailのテキストエリアに載せると文字化けが治ってました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/10/23 09:35

    ブラウザは何ですか?

    キャンセル

  • kei344

    2017/10/23 09:38

    project_loadも提示ください。

    キャンセル

回答 2

checkベストアンサー

+2

元データJSONがutf-8エンコードされているのであれば, reader.readAsBinaryString(file);の代わりにreadAsTextメソッドを使うのが筋では?

参考:https://developer.mozilla.org/ja/docs/Web/API/FileReader/readAsText

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/02 16:41

    readAsTextで読み込んだら文字化け直りました!ありがとうございます!

    キャンセル

+1

とりあえず以下の3つを確認してみてください。

  • 「文字化け」は JSON.parse(reader.result); 後も起こりますか?(というかパース出来ていますか?)
  • JSONが仕様どおりのフォーマットになっているか
  • HTML/JavaScriptの文字コードがUTF-8以外になっていないか

setTimeout(project_load,500); としてその中の関数から reader.result を呼んでいますが、エラーになると思います。引数で処理するほうが良いと思います。

【setInterval()やsetTimeout()で関数に引数を与えるには - Qiita】
https://qiita.com/kouhe1/items/9c23604901039832d385

また、readAsBinaryString は廃止されるようです。

【いつの間にかFileAPIのreadAsBinaryStringがオワコンになっていた。今後はreadAsArrayBufferで。 - anti scroll】
http://tategakibunko.hatenablog.com/entry/2015/08/25/115556

【FileReader.readAsBinaryString() - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/FileReader/readAsBinaryString

現在このメソッドは2012年7月12日付の W3C 草案に従って廃止されています。


追記:

下記記事の「このJSONをChrome Development Toolで読み込ませてみる。」の部分のスクリーンショットと同じ状況ですね。対処方法は再現環境が作れていないのでなんともいえませんが、エスケープ(backslash escapes)されているものをアンエスケープすれば多分いけると思います。

【boost::property_treeで日本語を含むJSONが文字化けする | Inhale n' Exhale】
http://h2plus.biz/hiromitsu/entry/728

あと、FileReaderで読み込むときのmimetypeを指定できれば自動変換されるのではないか、とも思います。(少なくともWeb上のリソースについてはそのような問題が起きにくいため、そう予想)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/23 10:28 編集

    JSON.parse(reader.result)の後も文字化けが起きます。
    readAsArrayBufferはもうちょっと勉強してみます。

    キャンセル

  • 2017/10/23 16:04

    コメント欄ではマークダウンが使えないため、質問本文に追記されてはいかがでしょうか。
    また、文字化け後の日本語部分も提示してください。

    > readerはグローバール変数にしている
    こちらの見落としでした。ただ、どこかで var するなどしてグローバール変数で無い使い方をされたほうが良いと思います。

    キャンセル

  • 2017/10/23 16:07

    本文に追加しました。ありがとうございます。

    readerは今デバッグで一時的にグローバル変数にしています。
    今後ローカル変数にする予定です。

    キャンセル

  • 2017/10/23 17:26

    編集ありがとうございます。「文字化け後」の文字列もいくつか提示いただけませんか?

    キャンセル

  • 2017/10/23 17:40 編集

    文字化け後のjson載せてみました。
    teratailにそのままコード載せようと思ったのですが、テキストエリアにペーストしたら文字化けが治っていたので画像で載せました。

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    17586questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • JSON

    1238questions

    JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。