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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

JavaScript

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

Q&A

解決済

1回答

1567閲覧

[JS] pngファイルで fileReader::readAsText()メソッドを使用すると値がおかしい

kazoogon

総合スコア281

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

JavaScript

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

0グッド

0クリップ

投稿2020/07/03 21:26

編集2020/07/04 08:33

環境

Chrome 83.0.4103.116
ruby on rails 3

目標

ファイルアップロードにて、手動でFileオブジェクトを作成しajaxでサーバーにデータを送る

問題点

[正常]
railsのviewにてfileをアップロードした場合(=<input type=file>をそのままformとしてアップロードした場合)下記データがサーバー内に保存されている

PNG  IHDRݡtEXtSoftwareAdobe ImageReadyqe<#iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 6.0-c002 79.164352, 2020/01/30-15:50:38 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop 21.1 (Windows)" xmpMM:InstanceID="xmp.iid:F66AE3CEAF0311EAA82AEE1161ABBC23" xmpMM:DocumentID="xmp.did:F66AE3CFAF0311EAA82AEE1161ABBChRy;\@d  X` X X`` X` X X`` X` X` X X`` X` X X`` X` X` X X`` X` X X`` X` X` X X`` X` X????axCp6escription> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>Ğ5IDATx39Ң"mP?$j*CT*)M[JRTQDI)r���^9;L śXzjJT74mBCtvN6/VzZ X^]^v.(uB(W:qT+Qؿ\ط\h;x,C0&k'WwڹtBF㦩Fo>Z|~bqkK쪹ፓ&[WۉW al۞:(>Pzb,6n}TsX;nUm-h_N 7>Ӽax.z+<>>ysEE]\}xkV&w>Bں V-szxV-X$·6ڣ!h˫[.XgWwV;#>!qQ5,bZ.\=z{Uo#w9Z֫WDtW7 =='_;6[ņٱ܄37.rtlE[źeыKفxG{j��Rtd4c&X!szj ϕ;:;tdˮ{H?ra̫:  ,{X']K[b~avegCaq..*y0a0Bxww`dg(6ҖB/ {|C!X;f޽څHaPēsXr][WC'/rj47NٱrtPAx(g_9:拚Ͼ~' E|7Rv~5FC}OZR ڌJ'w-fɾZJ!DױBO':{:{jB2L蟼0rR|پ%i7k],?X<vϔ#Jډ5͙D mނo|=<P~tm!]-k'I5LӋ`mWrB'\ӥ ÜCG8VuuL#7tT#6j(_۾zX;Or8?O㡹r77[Ur*e\jrѦn+.nMDW{o=4W||鎙Ϯr=15&{X ۗ,M#0ӵ/xi5ֿ{|x-|Iotұ< Oj|l`7NwUcz0j3#S짿zęo\-wc D~b��՜uwM>-C8US O>:.X ��f ?Ze_UÓV$n-L~Pyyjܞѵ_J>]՜ V9w[,ŋ M2 LXRzVa+I1۽zd7{Mu%NXjzVa$iK+V"ΉmRa V\6vԙ\;k"~Z0,>c%XsI-?LD,0P&8Z&!XK`g5/5o$簳ڮBbz'0`v; oP}>`+9xL *~Bb-|&ʹ|&LlU+EUf+n |dLgDg6xX} *,????ώ ho.byd/z{aXg֖B/l&BbdO-o~T,vp"<Qr<E' n{?'ؽm+ `Ʌmj[xb_I,��znPFvVh5 Q^j.-GW^%`fK-X嶸wq0P[KbbXA@#o enΣnޱXf/_r5&K/n}@wjK|{d!XdJRxf<Δc-?8bщ[O8^G'/XcyD,;Vg͕OV,^'>g6bScT7^2lz#:R';]˿?{6YÊF>< ✹, @ ,,@ @, @ ,,@ @, @2` X X`` X` X X`` X` X` X X`` X` X X`` X` X` X X`` X` X X``AG}>*urIENDB`

[異常]

const promiseTxt = convertFileToText(file); promiseTxt.then(function (data) { txt = data;//このtxtを最終的にサーバーに送る }) function convertFileToText(file) { return new Promise((res, rej) => { const reader = new FileReader() reader.onload = ((e) => { res(reader.result) }) reader.readAsText(file) }) } //サーバーに送るデータ, fileオブジェクトの作成 const file = new File([txt], ...(後は省略)

サーバー側で正常に保存されるが、中身が下記の通り(�の記号が多いように見える)

�PNG  IHDR��ݡ�tEXtSoftwareAdobe ImageReadyq�e<#iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 6.0-c002 79.164352, 2020/01/30-15:50:38 "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop 21.1 (Windows)" xmpMM:InstanceID="xmp.iid:F66AE3CEAF0311EAA82AEE1161ABBC23" xmpMM:DocumentID="xmp.did:F66AE3CFAF0311EAA82AEE1161ABBC23"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:F66AE3CCAF0311EAA82AEE1161ABBC23" stRef:documentID="xmp.did:F66AE3CDAF0311EAA82AEE1161ABBC23"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>Ğ5��IDATx�������a����������ؘ����39�Ң�"m��P�?$j�*C�T���*)M[�JR ������hR���y�������;��\��@d  X��` X� X�`�`� X��` X� X�`�`� X��`� X��` X� X�`�`� X��` X� X�`�`� X��`� X��` X� X�`�`� X��` X� X�`�`� X��`� X��` X� X�`�`� X��` X????ax�C�p6 �!X�����z�j��J�T7�4m�BC����t����v�N���6��/Vz�Z X���^]�^��v.(u��B(�W:�q����T+�Qؿ\ط\h;x,C0�&�k'�W��w�ڹt��BF�㦩Fo�>�Z|~���bq�k�K��쪹ፓ��&[Wۉ�W a�l�۞:�(>�Pzb�����,6��n�}�Ts�X;�n���Um���-�h��_���N� �7��>Ӽa��x����.���z+<>��>y��s�E���E]\�}xk���V&��w>B��ں�� V�-��s�zx�V-X$���·�6��ڣ��!��h��˫��[.��X��gWwV;#>!��q�Q��5�,b�Z��.\�=z{Uo#��w��9�Z�֫�W�D�ś�t�����W�7 ==����'�_;6���[�ņ��ٱ��܄��37.��rtl�E[�ź�e��ы�Kف�x�G�{j���Rt�d4��c��&�X�!���s�z������j �ϕ��;��:��W;�td�ˮ{H����?ra���̫�: 7 ��,{X�'���]K��[�b��~aveg���C��aq..*���y��0a�����0�B�xw��w�`��d�g(6ҖB/ {|C!X��;f��޽�څH�a���PēsX�r���][W�C�����'�/���r�j4�7�N��ٱr�t�P�Ax�(g_9:拚��Ͼ��~����'� E|�7�Rv����~�5F�C�}�O�ZR� � �ڌJ��'w-f�����ɾ�Z��J!�D��ױB����O��'���:{�:{j�B���2L蟼0�r�R��|�پ�%i7�k�],?�X<�v�����ϔ�#��J�ډ�5͙D�� ����mނ���o����|��=�<�P~�t���m!�����]��-��k'�I�5L�Ӌ�����`m���Wr��B'��\��ӥ� �Ü��CG�8V�u�u�L#7��� ��tT#6j����(��_۾z�X;�Or������8?�������O㡹�r77[�Ur���*e��\j�rѦn+�.��n��MDW{�o��=4W�����|���|鎙��Ϯ�r�=1������5�&{X �ۗ,M��#��0��ӵ/�xi5ֿ{|x-��|��Io�tұ<� Oj��|�l����`7N�wUcz0�j3��#��S�짿z��ę�o�\�-wc� �D��~b�����՜u�wM�>�-����C��8U���S����� O>�����:�.X ���f ?�Z�e����_����U��Ó�V$n�-L��~�P�y���y�jܞ�ѵ��_���J>����������]�՜� V��9���w�[,�ŋ� �M2� �LX��R�zVa�����+I���1۽zd��7�{�Mu�%�NX��j�zVa���$�iK+V�"�Ή���m���Ra�� �V�\6�v�ԙ�\;k"~Z�0,�>��c�%X�sI-���?L�D�,��0,��P�`�&�a8Z��&!X�K��`g5������/�5���o�$�簳ڮ��B�b��z'���0�`� *~�B�b��-�|&�ʹ��|���&�L�l�U+��E�U���f��+�n�� ��|d�LgDg6�xX}`�� ��*��,????ώ� �ho.��byd/�z{aX��g֖B/l&B�bdO-�o�~�T�,�vp"�<���Q�r�<���E��' ��n��{?�'�ؽ��m+ �`�Ʌ�m���j�[x���b�_I�,���znP�FvV�h���5�� Q���^�j.���-G��W�^%`�fK�-X�嶸�wq0P[K�bb��X�A�@#o �F�nt_ �)�L�`��X>���Z����0Pa�"�H�����F�-��r�U2���,��I�����t[��1\n$���T��Úk�=C2���P�b�ݛ�r��%c�J��+.#��Kݡ!!Õq�j���\:��Zӗ��ʦ}�+X����*H�p�K�h�i.�,� @� ,�8{�O�`���A@�H��ՎA�!!�` X� X�`�`� X��` X� X���e���nΣ�n���ޱ�X�����f�/_�r��5�&K����/����n�}@���wj�K���|{�d!X�d�J��Rxf�<�Δ��c���-��?8��bщ[��O8�^G'��/��X�c�y�D�,�;V��g�͕O�V�,^'���>g6b�S����c���T�7^�2�lz�#:��R';��]˿��?��{�6Y�Ê����F>< ��✹�,� @� ,�,@� @��,� @� ,�,@� @��,� @��2�` X� X�`�`� X��` X� X�`�`� X��` X��` X� X�`�`� X��` X� X�`�`� X��` X��` X� X�`�`� X��` X� X�`�`��A�G�}�>�*urIEND�B`�

fileReader::readAsText()を使用して、正常のパターンのようなデータを取得するのが不明で質問させていただきました。

追記1

1,arrayBufferを読み取り → 2,文字列としてdata属性に保存 → 3,サーバーにデータ送る時bufferArrayに戻す

1, function convertFileToText(file) { return new Promise((res, rej) => { const reader = new FileReader() reader.onload = ((e) => { res(e.target.result) }) reader.readAsArrayBuffer(file) }) } 2, const promise = convertFileToText(file); promise.then(function (arrayBuffer) { // array buffer to JSON (これをdata属性に保存) const dataString = JSON.stringify(Array.from(new Uint8Array(arrayBuffer))); }) 3, // JSON to ArrayBuffer const arrBuffer = new Uint8Array(JSON.parse(*data属性から取得)).buffer

ここで「Uncaught SyntaxError: Unexpected token , in JSON at position 3」のエラー
最初の質問とはずれるかもしれませんが、もし何か分かりましたらご回答いただけると助かります、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

fileReader::readAsText()メソッドを使用すると値がおかしい

テキストはエンコーディング仕様(文字コード)で定められたストリーム(バイトの並び)になりますが、バイナリファイルを readAsText() を使ってテキストとして読もうとすると、エンコーディング仕様と異なるストリームになるため、文字化けします(これを承知で binary-string として扱う時代もありました)。

正常のパターンのようなデータを取得するのが不明

MDN FileReader メソッド

  • バイナリファイルのストリームを操作する ... readAsArrayBuffer()
  • 文字列化してサイトデータに保存する ... readAsDataURL()
  • URLとして参照する ... URL.createObjectURL() / URL.revokeObjectURL()

PNG / APNG のファイルフォーマット関連情報

W3C PNG

MDN Animated PNG graphics

追記)

// サーバーに送るデータ, fileオブジェクトの作成

コード内コメントより、AjaxによるPOSTの事例について:

  • file オブジェクトは FormData.append() の第二引数に指定できます。

new File() も不要ですね。

html

1 <input type="file" id="upfiles" multiple> 2 <input type="button" id="checkfiles" value="確認">

javascript

1const makePostData = () => { 2 3 let formData = new FormData(), 4 upfiles = document.querySelector("#upfiles"), 5 key = upfiles.name || upfiles.id, 6 files = upfiles.files; 7 8 for( file of files ) { 9 console.log( file.name, file.type ); 10 formData.append( key, file, file.name ); 11 } 12 return formData; 13} 14 15window.addEventListener("DOMContentLoaded", () => { 16 17 let btn = document.querySelector("#checkfiles"); 18 btn.addEventListener("click", evt => { 19 let formdata = makePostData();// ユーザ関数 20 // formdata を Ajax送信 21 }); 22});

追記2)

arrayBufferについて「追記1」として記載させていただきました(コメント欄)

ご質問の追記内容 2.3. では、binary-string(文字列)化することに執着しているようですが、Ajaxで FormData を 送信する方針もあります。
簡単ですが以下のような手順になるかと思います。

  1. var file=new File([arraybuffer],"foo.png",{type:"image/png"});
  2. formData.append("upfiles", file, file.name );

"upfiles" は input[type=file] の name 属性に相当。
3. Fetch を使う の「ファイルアップロード」の項(FormData を使ったファイルアップロード例)

投稿2020/07/03 21:48

編集2020/07/04 09:00
AkitoshiManabe

総合スコア5434

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

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

kazoogon

2020/07/03 22:27

ご回答ありがとうございます。 今回の場合 readAsBinaryString() と思い修正し文字化けは無くなりましたがまだ正常なpngとして認識されてないですね。。。
AkitoshiManabe

2020/07/03 22:36

最後に追記している通りで、file オブジェクトは convert 不要です。FormData.append() の第三引数に ファイル名を与えて AjaxでPOSTしてみてください。multipart/form-data で送信されるはずです。
kazoogon

2020/07/03 22:57

そのfileオブジェクト第一引数に指定するデータは readAsBinaryString() のデータは間違いですかね??
kazoogon

2020/07/04 06:37

> new File() も不要ですね。 今回分かりやすいようにはしょってましたが、inputでファイル選択 → previewとしてみる → upload というfacebook messangerの様な機能でinputそのまま使用できないので、こちら質問致しました。 ですので一回previewしているdiv要素のdata属性にファイルデータを入れる ↓ そこのdata属性からデータ取得してFile object作成しております
kazoogon

2020/07/04 08:34

arrayBufferについて「追記1」として記載させていただきました。もし何か分かりましたらご回答いただけると幸いです
kazoogon

2020/07/04 09:10

追記2)ありがとうございます > binary-string(文字列)化することに執着している data属性に一回保存する方法として文字列を考えております。 DOM上ではなく、jsの変数に保存する方法があると思いますが、できるならdata属性として保存したいです > var file=new File([arraybuffer],"foo.png",{type:"image/png"}); このFileオブジェクト作成時の [arraybuffer] のデータが正常に取得できずに困っているという状態です。 そのあとのformData.append("upfiles", file, file.name );はこちらで問題なく動きます
AkitoshiManabe

2020/07/04 09:20

> inputでファイル選択 → previewとしてみる → upload のコードが無かったので避けていましたが、 preview の際に「スコープを意識した変数」に格納しておくのはどうでしょうか。 input.files が参照できれば、1回目の追記の通り、 File を使わなくても良いように感じますねぇ。
kazoogon

2020/07/04 09:23

やはりdata属性ではなく、JSの変数に保管したほうがやりやすいですかね。。。汗 一回その方針でやってみます! ご回答非常に助かっております、ありがたいです!
kazoogon

2020/07/04 17:45

jsの変数利用してfileオブジェクトを保存しといて、それをサーバーに送る時はformData.append("file", FileObject); のようにする方法でいけました(そりゃそうですが汗) 一応これで解決と致します、ご回答ありがとうございました。
AkitoshiManabe

2020/07/04 22:02

data属性の場合は、パーセントエンコーディング(encodeURIComponent)した文字列が安全ですが、現在のPNGは画像サイズも大きく、比例して文字数が大きいので、モダンな FormData 送信で済ませるのがベターですね。 とにかく、解決されて何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問