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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

3526閲覧

Node.js / React / encoding.js 文字エンコード 文字化けについて

bizinesuwa

総合スコア2

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1グッド

1クリップ

投稿2023/02/24 10:06

実現したいこと

CSVアップロード時の文字化けを解消したい。

前提

閲覧いただきありがとうございます。

Node.js / React でのプログラムを勉強中ですが、
どうしても文字エンコードが上手く出来ず(文字化けが解消出来ず)、こちらに質問させていただきました。

色々なサイトを拝見し、文字エンコードについてサンプルコードを改変しながら実行してきましたが、
解決の糸口が見当たらず、現在に至っております。。。
「react upload 文字化け」「react csv 読み込み」等

まだプログラムの意味も一行ずつ理解する初心者では御座いますが、
ご教授・参考サイト等、ご教授、ご指摘頂ければ幸いです。

どうぞ、よろしくお願い致します。

該当のソースコード

import React from 'react' import { useState } from 'react' import Encoding from 'encoding-japanese'; import { parse } from 'papaparse' function ReadString() { const [data, setData] = useState([]) return ( <> <div style={{height: "100px", width: "100%", background: "#ddd"}} onDragOver = {(event) => { event.preventDefault() console.log('onDragOver') }} onDrop = {(event) => { event.preventDefault() // console.log('onDrop') console.log(event.dataTransfer.files) Array.from(event.dataTransfer.files).map( async file => { let text = await file.text() console.log(encoding) const encoding = Encoding.detect(text); const unicodeString = Encoding.convert(text, { to: 'unicode', from: encoding, type: 'string', }); let result = parse(unicodeString, { header: true, dynamicTyping: true, skipEmptyLines: true, }) console.log(result) setData(result.data) }) }} > </div> </> ); } export default ReadString;

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ページエンコード:UTF-8
アップロードファイル:Shift-JIS
└ アップロードするファイルは、PCで開くと Shift-JIS ですが、コード内 console.log(encoding) では、UNICODE と出ています。

"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"papaparse": "^5.3.2",
"encoding-japanese": "^2.0.0",

miyabi-sun👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ReactはいわゆるJSフレームワークと呼ばれるものです。
HTMLテンプレートっぽいものを読み込ませてDOMツリーを作っている状態で
React世界の変数の値を更新すると最新のDOMツリーに勝手に書き換わってくれる事が特徴です。

基本的にこれ以外の仕事はしません
色んなライブラリを肉付けしてくれる人は居ますが、
Reactの仕事と文字コードの変換はかけ離れているのでそんなライブラリ作っている人も皆無でしょう。


次に基本的な文字コードの説明をします。
世の中の文字コードはすでにUTF-8を中心に回っています。
今どきShift-JISを使っているのはWindowsくらいのものです。

ブラウザやJavaScriptファイル等が動いている環境、とりまく環境も全てUTF-8です。
一応大昔の日本語サイトにはShift-JISで書かれているものもありギリギリ文字化けせずに表示してくれますが、
一応Webブラウザが対応しているというだけの話です。

内部のJavaScript変数世界はUTF-8環境であり、Shift-JISを扱えて当然というわけではありません。

そういう事情があるので「react upload 文字化け」「react csv 読み込み」等のワードで検索するのは無駄です。
今回のケースでは、JavaScript+文字コードの問題でしかないので
DataTransfer.filesは何者やねんの切り口から追っていく必要があります。

Array.from()は配列っぽいけど配列ではないものに対して
配列として動くよう強要する命令です。
つまりevent.dataTransfer.filesは配列ではない?

では何者なのか?
MDNが結構詳しくて正確なので探してみましょう。

なるほど、Fileの集まりなわけですね。
そしてFileにはこれらのメソッドが生えているようです。

  • text()→Promise<String>で取り出す
  • arrayBuffer()→Promise<ArrayBuffer>で取り出す

JavaScriptはUTF-8で動いているので、
Shift-JISのファイルをtext()メソッドを使って取り出してしまったら、
その時点でバイナリデータを無理やりUTF-8で読み込もうとして文字が潰れてしまいます。

こうなると手の施しようがないので、
バイナリデータのまま吸い上げる必要があります。
つまりarrayBuffer()メソッド一択です。


続いてnpmのencoding-japaneseも見に行きましょう。

Exampleとかにちゃんと書いてあるじゃん。
String型としてShift-JIS扱ってないよね?

js

1const unicodeArray = Encoding.stringToCode('こんにちは'); // Convert string to code array 2const sjisArray = Encoding.convert(unicodeArray, { 3 to: 'SJIS', 4 from: 'UNICODE' 5}); 6console.log(sjisArray); 7// [130, 177, 130, 241, 130, 201, 130, 191, 130, 205] ('こんにちは' array in SJIS)

JavaScriptやNode.jsではUTF-8以外扱えないから、
配列に数値突っ込んでいる擬似的なShift-JISになりますよって言ってるわけです。
(まぁ、この辺の事情はJavaScriptがUTF-8でしか動かないと知らなければわからないと思います)

バイナリデータというのは00-FFの羅列
これを16進数に変換すると0-255の数字の配列と読み替える事が可能です。

encoding-japaneseもUint8Arrayなら扱えるという話なので
ArrayBufferから一度Uint8Arrayに変換すれば良いでしょう。

js

1var utf8Array = new Uint8Array(ArrayBuffer); 2Encoding.convert(utf8Array, 'SJIS', 'UTF8');

ArrayBuffer -> Uint8Arrayの変換に関して
どういう原理なのかは下記の記事が参考になると思います。
http://var.blog.jp/archives/62330155.html

投稿2023/02/24 12:30

編集2023/02/24 16:12
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2023/02/24 16:08

お疲れ様、これ別の側面から原因をある程度知っていないと 正解にたどり着くのがかなり難しい部類の問題です。 この時点で質問に来るのは良いタイミングであり、 回答者の私に通じるような質問文も書けてるし、非常に良い質問だと思います。
bizinesuwa

2023/02/24 21:53

この度は質問した内容に対して、このような分かりやすい説明を頂き、本当にありがとうございます。 text()に何をしても既に手遅れで、こちらで回答を頂かなければ解決出来ないままでした。 文字の取り扱いだけでなくReactについて、まだまだ知識が乏しいですが、 参考URLにも大変有益な情報まで案内いただき、新しい知識が増えそうです。 本当にありがとうございます。
guest

0

JavaScript 変数世界というのが何を表しているのか分かりませんが、
JavaScript の内部エンコーディングは UTF-8 ではなく、UTF-16 (昔、間違って Unicode と呼ばれていたもの) ですよ。

JavaScript の文字コードは UTF-16 だった
http://var.blog.jp/archives/48794227.html
文字列とUnicode · JavaScript Primer #jsprimer
https://jsprimer.net/basic/string-unicode/
【JavaScript】 文字列データの内部形式と関連メソッドについてまとめてみた
https://note.affi-sapo-sv.com/js-character-code.php

投稿2023/03/01 10:25

Lightfox

総合スコア28

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問