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

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

ただいまの
回答率

90.33%

  • JavaScript

    17542questions

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

  • CSV

    710questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • UTF-8

    115questions

    UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

JavaScriptでcsvファイルを読み込んでブラウザに出力したいのですが、文字化けしてしまいます。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 5,363

chibi

score 14

JavaScriptでcsvファイルを読み込んでブラウザに出力したいのですが、文字化けしてしまいます。
csvはutf-8で保存しています。サーバーは、Xサーバーです。
文字化けせずにcsvファイルから読み取り、出力するにはどうすれば良いでしょうか?

test.csv
20170404,イチロー,いちご
function getCSV(){
    var req = new XMLHttpRequest();
    req.open("get", "test.csv", true);
    req.send(null);

    req.onload = function(){
    convertCSVtoArray(req.responseText);
    }
}

function convertCSVtoArray(str){
    var tmp = str.split(",");
    alert("データ1:"+tmp[0]+"データ2:"+tmp[1]+"データ3:"+tmp[2]);
}
getCSV();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • 07JP27

    2017/04/05 08:12

    表示するHTMLのheadに<meta charset="UTF-8" />は書かれていますか?

    キャンセル

  • chibi

    2017/04/05 21:17 編集

    回答していただき、ありがとうございます!<meta charset="UTF-8" />は書いています。

    キャンセル

  • Lhankor_Mhy

    2017/04/08 15:07

    文字化けした出力結果を見せていただくことは可能ですか?

    キャンセル

回答 1

+6

次のようなスクリプトで実験してみました。

<!DOCTYPE html>
<html lang="ja">
<head>
 <meta http-equiv="Content-Type" content="text/Shift-JIS; charset=utf-8" />
 <title>csv test</title>
 <script type="text/javascript">
//---------- from ----------
function getCSV(){
  var req = new XMLHttpRequest();
  req.open("get", "test.csv", true);
  req.send(null);

  req.onload = function(){
    var reshdr = req.getResponseHeader("content-type") //for debug
    console.log(reshdr)                                //for debug
    convertCSVtoArray(req.responseText);
  }
}

function convertCSVtoArray(str){
    var tmp = str.split(",");
    alert("データ1:"+tmp[0]+"データ2:"+tmp[1]+"データ3:"+tmp[2]);
}
//---------- to ----------
 </script>
</head>
<body>
 この行はShift-JISでエンコードしてあります。
 <form>
  <input type="button" value="show csv" onClick="getCSV()">
 </form>
</body>
</html>
  • HTML自体はShift-JISでエンコード
  • ブラウザー(firefox: テキストエンコーディングを「日本語(Shift-JIS)」「自動判別:解除」)
    上記ページのボタンをクリックするとalertの内容は文字化けしていませんでした。
    なお、上記javascriptでcsvファイルを受け取ったときのレスポンスヘッダーの"content-type"をコンソールに出していますが"text/csv; charset=UTF-8"となっていました。

また、サーバーはちょっといい加減なものを使っており応答の際にcharsetを無条件にutf-8にしているのですが、firefoxのテキストエンコーディングを「unicode」「自動判別:解除」にするとHTMLドキュメント上の文字列やalertの「データ1」などは文字化けしますが、受信したcsvデータ自体は文字化けしません。

つまり「サーバーから応答されたtest.csvのレスポンスがcharset=utf-8になっていないかまたはサーバー上にあるtest.csv自体がutf-8でないかのいずれかではないかと思いました。


追記:まず事実を確認してみるとよいと思います。

  • server上のtest.csvはutf-8になっているか

小さなテストデータなので確認は容易だと思います。例えばlinux/unix上であれば下記と同じ結果になればutf-8であることは確実です。(通常はLANG=ja_JP.UTF-8となっている端末上でcat test.csvとして文字化けしてなければutf-8であるといった確認をするでしょうけども)

$ od -c test.csv
0000000   2   0   1   7   0   4   0   4   , 343 202 244 343 203 201 343
0000020 203 255 343 203 274   , 343 201 204 343 201 241 343 201 224  \n
0000040
  • serverからtest.csvを受信した際のcharset
    上述の実験コードのようにリクエストオブジェクトに対してgetResponseHeader("content-type")メソッドの呼び出しで文字セットが確認できます。

補足しますと、自分はwebアプリケーションの知識に乏しいため、「どういう確認ができるか」を考え上記のような実験をしてみた次第です。まず上記を確認して「推測した通りの不整合がみつかったなら」その先を調査するようにしたほうがよいでしょう。サーバーからの応答のcharsetがutf-8になっていないかも知れないという推測のままで前へ進むのは時間を無駄にする可能性があると思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/05 22:58 編集

    回答をいただき、また実験までしていただき、ありがとうございます。
    >つまり「サーバーから応答されたtest.csvのレスポンスがcharset=utf-8になっていないかまたはサーバー上にあるtest.csv自体がutf-8でないかのいずれかではないかと思いました。

    test.csvはutf-8になっているので、「サーバーから応答されたtest.csvのレスポンスがcharset=utf-8になっていない」のかもしれません。その場合はどうすれば良いのでしょうか?

    キャンセル

  • 2017/04/06 05:12

    > 「サーバーから応答されたtest.csvのレスポンスがcharset=utf-8になっていない」のかもしれません。

    こうした場合、まず事実を確認するのがよいと思います。

    キャンセル

  • 2017/04/06 09:30

    macなのですが、test.csvのレスポンスを確認するにはどうしたら良いのですか?

    キャンセル

  • 2017/04/06 10:06

    回答の追記部分をごらんいただければと思います。

    キャンセル

  • 2017/04/06 11:42

    コンソールに、下記のように出ます…。
    Uncaught ReferenceError: getCSV is not defined
    at HTMLInputElement.onclick

    キャンセル

  • 2017/04/06 12:28

    javascriptの関数getCSVを私のサンプルコードのよう書いて、そのHTML内で使えるように定義してください。

    scriptタグの書き方について少々知識不足の点がありそうですね。そこをまずは学んでおいてください。そこが曖昧だとHTMLを書くのが厳しいと思います。

    キャンセル

  • 2017/04/07 03:57

    エラーは出なくなりましたが、コンソールに何も表示されません。

    キャンセル

  • 2017/04/07 05:08 編集

    当方にはchibiさんがどのようなスクリプトを書いていてどのようなテストをされているかはわかりません。意図通りに動かなかった場合、なんらかの手がかりをつかむことが肝心と思います。コンソールに何も表示されなかったのなら、console.logが実行されなかったか、実行されたがブラウザーの設定かなにかでログが残らないケースがあるのか(そういうことがあるかどうか自分にもわかりません)またはconsole.logが出たかどうかの確認の仕方をchibiさんが間違っておられるのか…どういう可能性があるか自分にははっきりわかりません。ためしにgetCSVの先頭でconsole.log('abc')とやってそれがブラウザーのデバッグコンソールに出るかどうか試してみてはいかがでしょう?

    キャンセル

  • 2017/04/07 05:46 編集

    ;をつけるのを忘れてたのですが、;をつけたら、コンソールに「text/csv」と出ました。これはutf-8じゃないってことなんでしょうか?

    キャンセル

  • 2017/04/07 10:09 編集

    自分も追加で実験しました。
    サーバーの動作を変更しレスポンスのContent-Typeを"text/csv"のみにしましたが文字化けは起きません。(念のためcsv受信時のレスポンスをブラウザーのplug-in(HttpFox)と、上記回答に示したJavascriptからのconsole.log出力の両方確認しましたが、charsetは確かに無指定になっています。)この辺りになると自分の知識範囲ではあやふやな推測しかできません。XMLHttpRequestオブジェクトはAjaxに使われる組み込みモジュールということらしいので、動作はブラウザーに依存すると推測します。自分のテスト環境はWindows10(64bit)、Firefox 52.0.2(32bit)「エンコーディングはunicode、自動判別解除」の状態です。chibiさんの環境をできるだけ詳しく書くと詳しい方がコメントくださるかも知れません。質問を編集して情報を追記してみてはどうでしょう?
    ---
    ちなみに自分の環境でもサーバー設定を変更し、わざとうそのcharset(Shift_JIS)を送信するとちゃんと(w;)文字化けしました。

    キャンセル

  • 2017/04/07 10:17

    ところで、原因究明とは別に解決方法なら自分にもいくつか思いつきます。どうすべきか判断に自身がないですが・・・
    (1) サーバーから、レスポンスヘッダーにtext/csv; charset=UTF-8を応答するようにする。
    =>chibiさんがサーバーサイドの開発責任をもっているか設定に文句を言える立場ならこれがよいのではないでしょうか。
    (2) サーバーの設定を変更できない事情があるとき、ブラウザ側で無理やりContent-Typeを上書きしてしまう。(よくわからないですが、これは乱暴な方法に思えます。)XMLHttpResponseにoverrideMimeTypeという関数がありそれで上書きできます。具体的には`req.send(null);`の直前に
    `req.overrideMimeType('text/csv; charset=UTF-8');`の行を挿入するとできます。

    キャンセル

  • 2017/04/07 11:59 編集

    `req.send(null);`の直前に`req.overrideMimeType('text/csv; charset=UTF-8');`を挿入してみたのですが、文字化けが解消されないです…。

    キャンセル

  • 2017/04/07 12:30

    ということは自分の環境(Win10, Firefox)とは明らかに動作が異なりますね。自分の環境ではそこに
    text/csv; charset=Shift_JIS
    を上書きしてやるとちゃんと(w;)文字化けしますよ。つまりoverrideMimeTypeの指定に従ってレスポンスの文字列がデコードされる動きになっています。やはりchibiさんの環境を詳しく書かれた方がよいと思います。またサーバーの設定変更ができる立場にあるかどうかも書かれた方がよいと思います。

    キャンセル

  • 2017/04/07 12:40 編集

    サーバーの設定変更する権限はありますが、どうやるか分からないです。

    キャンセル

  • 2017/04/07 12:42

    ところで、回答の「追記」に書きましたが、サーバー上にあるtest.csvをodコマンドなどでダンプした結果は自分の回答と同じデータになったでしょうか?またwebサーバーの種類や設定を質問文に追記することをお勧めします。閲覧者のみなさんがあなたの環境を知れば知るほど解決は早くなると思います。

    キャンセル

  • 2017/04/07 12:44

    > サーバーの設定変更する権限はありますが、どうやるか分からないです。
    それは自分にはどうにもできないです。自分は自宅のWin10上にnodejsで適当に書いたserverを動かしているにすぎずまともなwebサーバー(アパッチとか?)は一度も触ったことがないのです...

    キャンセル

  • 2017/04/07 21:55

    odコマンドでダンプするのは、htmlの中に書けば良いのですか?

    キャンセル

  • 2017/04/07 22:07 編集

    いえ、odはunix系OSで使えるコマンドです。端末を開いてそのシェル上で動かしてみてください。Macもunix系OSですから使えると思います。(webサーバーがMacだと思っているのですが違ったらスミマセン)

    キャンセル

  • 2017/04/08 03:37

    ターミナルで入力してみたのですが、
    od: test.csv: No such file or directory
    od: test.csv: Bad file descriptor
    と出ました。

    キャンセル

  • 2017/04/08 11:45

    すみません。自分の方が見落としてました。Xサーバーと書いてありますがレンタルサーバーということですね?

    キャンセル

  • 2017/04/09 06:07

    はい、そうです。

    キャンセル

  • 2017/04/09 09:59

    >ターミナルで入力してみたのですが・・・
    というのはXサーバーへSSHで接続してそこでやってみたということですね?サーバーのOSが何かわかりますか?

    キャンセル

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

  • JavaScript

    17542questions

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

  • CSV

    710questions

    CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

  • UTF-8

    115questions

    UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。