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

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

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

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2554閲覧

jsonを使ったファイルの送受信について

_ecs

総合スコア9

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

JavaScript

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/11/17 01:01

編集2020/11/17 01:51

前提・実現したいこと

jsでpngの画像をbase64エンコードしてjsonとしてPOSTし、pythonでそのエンコードされた文字列をデコードし、pngとして保存しようと思っております。
以下のようにコードを書いているのですが、保存時にファイルが壊れて開けません。
どうすればきちんと保存できるか教えていただきたいです。

該当のソースコード

javascript

1//エンコード 2btoa(encodeURIComponent(the_file.target.result))

python

1#デコードして保存 2with open(path, 'w', encoding='utf-8') as f: 3 f.write( 4 urllib.parse.unquote( 5 base64.b64decode( 6 validated_data['content'] #jsでエンコードされた文字列 7 ).decode() 8 ) 9 )

追記:全体のコード

javascript

1// cookie取得 2const get_cookie = name => { 3 let cookieValue = null; 4 if (document.cookie && document.cookie !== '') { 5 const cookies = document.cookie.split(';'); 6 for (var i = 0; i < cookies.length; i++) { 7 let cookie = jQuery.trim(cookies[i]); 8 if (cookie.substring(0, name.length+1) === (name+'=')) { 9 cookieValue = decodeURIComponent(cookie.substring(name.length+1)); 10 break; 11 } 12 } 13 } 14 return cookieValue; 15} 16 17class Transmission { 18 constructor(method, content, func) { 19 this.method = method; 20 this.content = content; 21 this.func = func; 22 this.__proto__.csrftoken = get_cookie('csrftoken'); 23 } 24 25 send(url) { 26 fetch(url, { 27 method: this.method, 28 credentials: "same-origin", 29 headers: { 30 "Accept": "application/json", 31 "Content-Type": "application/json", 32 "X-CSRFToken": this.csrftoken, 33 }, 34 body: JSON.stringify(this.content) 35 }) 36 .then(response => { 37 if(response.ok) { 38 return response.json(); 39 } else { 40 throw new Error("not found..."); 41 } 42 }) 43 .then(data => { 44 // thisの束縛 45 this.func(data); 46 }) 47 .catch(e => { 48 console.log(e.message); 49 }); 50 } 51} 52Transmission.uid = get_cookie('uid'); 53 54 55{ 56 let file_name = file_content = null; 57 // ファイル中身を展開しbase64エンコード 58 document.querySelector('.custom-file-input').addEventListener('change',function(e){ 59 const file = document.getElementById("input_file").files[0]; 60 const next_sibling = e.target.nextElementSibling; 61 file_name = file.name; 62 next_sibling.innerText = file_name; 63 if (1 <= document.getElementById("input_file").files.length) { 64 let reader = new FileReader(); 65 reader.onload = the_file => { 66 file_content = btoa(encodeURIComponent(the_file.target.result)); 67 } 68 reader.readAsText(file, "utf-8"); 69 } 70 }); 71 72 // document.getElementById("send").addEventListener("click", e => { 73 // const cmd = document.getElementById("cmd"); 74 // if(cmd.value != "") { 75 // let content = { 76 // sender: Transmission.uid, 77 // cmd: cmd.value, 78 // recipient: "00-FF-CE-89-86-5B" 79 // } 80 // if(file_name != null && file_content != null) { 81 // content["name"] = file_name; 82 // content["content"] = file_content; 83 // } 84 85 // tran = new Transmission( 86 // "POST", 87 // content, 88 // (data) => { 89 // console.log(data); 90 // } 91 // ); 92 // tran.send("http://127.0.0.1:8000/api/command/?format=json"); 93 // } 94 // }); 95 document.getElementById("send").addEventListener("click", e => { 96 const cmd = document.getElementById("cmd"); 97 if(cmd.value != "") { 98 let content = { 99 response: "hogheoh", 100 } 101 if(file_name != null && file_content != null) { 102 content["name"] = file_name; 103 content["content"] = file_content; 104 } 105 106 tran = new Transmission( 107 "PATCH", 108 content, 109 (data) => { 110 console.log(data); 111 } 112 ); 113 tran.send("http://127.0.0.1:8000/api/command/2/?format=json"); 114 } 115 }); 116 console.log(document.getElementById("target").value); 117} 118 119

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

python3
django rest framework

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

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

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

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

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

yambejp

2020/11/17 01:05

> pngの画像 は、どうやって持ってきているのですか?
_ecs

2020/11/17 01:26

{ "upfile": { "name": "can.png", "content": "JUVGJUJGJUJEUE5HJTBEJTBBJ...." } } このようなjsonをjsでPOSTし、pythonで受け取っています。 validated_data["content"]は上記のjsonのcontentを取得しており、contentはjsでファイルの中身をbase64エンコードした文字列となっています。
yambejp

2020/11/17 01:28

いえそうでなくて the_file.target.result はどこからどうやって参照しているのですか?ということです
_ecs

2020/11/17 01:31

失礼しました。コードを追記させていただきました。
yambejp

2020/11/17 01:33

なるほど、input=typeからfilereaderで処理しているのですね? formdataではだめですか?
退会済みユーザー

退会済みユーザー

2020/11/17 01:35

Data url 形式になっていて、その文字列先頭の data:image/png;base64, を除去しないでデコードしようとしているとかはないですか?
yambejp

2020/11/17 01:42

そもそも単にpostするだけならサブミットするだけでは? 非同期処理とか必要なのでしょうか?
_ecs

2020/11/17 01:45

>>yambejpさん formdataであればそのまま送って、受け取り保存することができるのですか? >>SurferOnWwwさん デコード前の文字列を確認してみたのですが、ついてなさそうでした...
_ecs

2020/11/17 01:49

>>yambejpさん djangoでREST APIを作っていまして、jsonを受け取りjsonを返す。ということを目標につくっているのと、 返ってきたjsonを遷移せずに画面反映させたいため非同期で処理させたいのです。
guest

回答3

0

javasacript

1// arraybufferをbase64エンコード 2const buffer_to_base64 = buffer => { 3 let binary = ''; 4 const bytes = new Uint8Array(buffer); 5 const len = bytes.byteLength; 6 for (let i = 0; i < len; i++) { 7 binary += String.fromCharCode( bytes[i] ); 8 } 9 return window.btoa(binary); 10} 11let file_name = file_content = null; 12 // ファイル中身を展開しbase64エンコード 13 document.querySelector('.custom-file-input').addEventListener('change',function(e){ 14 const file = document.getElementById("input_file").files[0]; 15 const next_sibling = e.target.nextElementSibling; 16 file_name = file.name; 17 next_sibling.innerText = file_name; 18 if (1 <= document.getElementById("input_file").files.length) { 19 let reader = new FileReader(); 20 reader.onload = the_file => { 21 file_content = buffer_to_base64(the_file.target.result); 22 } 23 reader.readAsArrayBuffer(file); 24 } 25 });

バイナリファイルなのでreadAsArrayBufferでした...
ポンコツなミスお許しください

投稿2020/11/17 04:36

_ecs

総合スコア9

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

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

yambejp

2020/11/17 04:38

なんかダブってます?
_ecs

2020/11/17 04:49

ダブりました... 503エラーで投稿できてないと思ったのですができていたようです。申し訳ないです
guest

0

javascript

1// arraybufferをbase64エンコード 2buffer_to_base64 = buffer => { 3 let binary = ''; 4 const bytes = new Uint8Array(buffer); 5 const len = bytes.byteLength; 6 for (var i = 0; i < len; i++) { 7 binary += String.fromCharCode( bytes[i] ); 8 } 9 return window.btoa(binary); 10} 11 12let file_name = file_content = null; 13 // ファイル中身を展開しbase64エンコード 14 document.querySelector('.custom-file-input').addEventListener('change',function(e){ 15 const file = document.getElementById("input_file").files[0]; 16 const next_sibling = e.target.nextElementSibling; 17 file_name = file.name; 18 next_sibling.innerText = file_name; 19 if (1 <= document.getElementById("input_file").files.length) { 20 let reader = new FileReader(); 21 reader.onload = the_file => { 22 file_content = buffer_to_base64(the_file.target.result); 23 } 24 reader.readAsArrayBuffer(file); 25 } 26 });

バイナリファイルなのでreadAsTextでなくreadAsArrayBufferでした...
お騒がせしてすみませんでした。

投稿2020/11/17 04:04

_ecs

総合スコア9

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

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

0

ベストアンサー

ファイルをjsonにするという意図がよくわかりません。
非同期で単純に処理するならこんな感じ

投稿2020/11/17 01:47

yambejp

総合スコア116724

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

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

yambejp

2020/11/17 01:47

<script> window.addEventListener('DOMContentLoaded', ()=>{ document.querySelector('#hoge').addEventListener('change',(e)=>{ const url='・・・'; const method='post'; const body=new FormData(); body.append(e.target.name,e.target.files[0]); fetch(url,{method,body}).then(res=>res.text()).then(console.log); }); }); </script> <input type="file" name="hoge" id="hoge">
_ecs

2020/11/17 01:53

ありがとうございます。 formdataで試してみます。
yambejp

2020/11/17 02:04 編集

formdataの場合フォームごとまとめて指定してしまうことが多いです new FormData(form)的な感じ(formはDOMで掴んだform要素) (個別のinput要素ごとだと例示したような書き方になります)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問