- ベストアンサー
WordPressでのファイルアップロードの選択肢
- WordPressでFetch APIを利用してファイルをアップロードする方法が困難であることに悩んでいる。
- Ajaxを使ったファイルアップロード方法は多く存在するが、データベース保存が見つからず、サーバーディレクトリ保存が推奨される。
- 適切なアップロード方法を選定する際に、Fetch APIの利用可能性が判断基準となる。
- みんなの回答 (39)
- 専門家の回答
質問者が選んだベストアンサー
・ローカルストレージなどに保存しないと入力内容が消えるのではないかというアドバイス これは私は疑問に感じています。 消えるのかどうかわからないです。 どちらかと言うと消えないと思っています。 必ず消えるとかでないのなら、消えた場合に入力画面に戻るようにして、再入力してもらえばいいと思います。 消えないと言うか消えてもいいと言うか、セッションならこれは問題になりません。 私が想像しているセッションを使う場合の補足ですが、セッションは確定した登録用のものです。 表示切り替えはクライアント側のデータをそのまま使いまわします。 なのでサーバー側(セッション内容)とクライアント側のデータに相違があることがあるかもしれません。 それは確認画面まで進んでクライアント側のデータが改ざんされた場合ですが、それは無視します。 安全で確定したセッション内容を優先するからです。 そうすれば、確認画面から結果画面へ行く時は、「確認画面から結果画面へ行くよ」と言う情報しか(改ざんされたデータがない)サーバーに送信しないので安全です。
その他の回答 (38)
- dell_OK
- ベストアンサー率13% (766/5720)
・入力画面に戻る機能を付けたい場合、フォームから一時ファイルに保存する必要がありそうです。 戻ると言っても非表示にした要素を表示するだけですからそんなことはないと思っていますが、もしそれでするなら、入力画面は非表示ではなく要素削除の方がいいかも知れないですね。 アドバイスくださった人もそのつもりでそう言われたような気がします。 保持している別の領域からデータを復元するので、要素を残したままでデータが残っているのはどうなのかなと思いますし。 アップロードファイルはinput要素として戻せないのでbase64で保存しておいて表示することになるのでしょうね。 確認画面からの送信はそのbase64を送ることになるのでしょうね。
補足
A.回答ありがとうございます、入力フォームから送信したものを一時ファイルに保存するような形になるのでしょうか?… 一時保存するという意味がよくわからないのですが、入力フォームから非同期通信を利用してサーバーに送信?する際に一時保存するコードの想像がつかないです… dell_ok さんは分かりますでしょうか? 確認フォームから送信後に入力フォームを再度表示させる際は要素を削除して入力フォームのHTMLをJavascriptで生成するようなイメージで考えております。
- dell_OK
- ベストアンサー率13% (766/5720)
・画面をリダイレクトさせる形で確認画面からサーバーに送信してコメントを表示&入力画面を表示させるという事でしょうか? リダイレクトしません。 全部非同期通信して、JavaScriptで画面を書きかえます。
補足
回答ありがとうございます、質問してみたところ下位のようなアドバイス頂きました。入力画面に戻る機能を付けたい場合、フォームから一時ファイルに保存する必要がありそうです。 ※頂いたアドバイス JavaScript で確認画面を出すとなると、ローカルストレージなどに保存しないと入力内容が消えるかと思います。 ReactやVueなどのフレームワークを使う場合だと、FluxやVuexといった変数などをグローバルで管理できる機能を使って、画面を切り替えても流用できる方法が採れますが、JavaScriptだとその方法が採れませんね。 https://qiita.com/masuda-sankosc/items/cff6131efd6e1b5138e6
- dell_OK
- ベストアンサー率13% (766/5720)
少し試してみました。最後までは見てないので確実ではないですが。 ファイルのアップロードはセッションでいけそうな感じでした。 セッションを使うとなると、名前やコメントもそれでいいような気がするので、確認画面をフォームにする必要がなくなる気がします。 確認画面をフォームにすると言われてた人に、セッションを使った場合はフォームでなくてもいいか聞いた方がいいかも知れません。
補足
回答ありがとうございます、入力画面から確認画面でセッションを使う事は問題ないと思うのですが、 画面をリダイレクトさせる形で確認画面からサーバーに送信してコメントを表示&入力画面を表示させるという事でしょうか? おそらく2択の方法があるようですべて非同期通信でする場合のファイルアップロード&サーバーに送信後に入力画面に戻す方法を質問して聞いてみます。
- dell_OK
- ベストアンサー率13% (766/5720)
訂正します。 直接こうするのも、 form.enctype = "multipart/form-data"; opt で設定するのもよくなかったです。 <input type="file">にファイルを設定することが禁じられているためです。 ファイルアップロードについては、入力画面からの送信時に、セッションを使うか、一時ファイルに保存する必要がありそうです。 セッションを使うのであれば、もとの方法に近い処理になると思います。 できるのかどうかわからないのでサンプルで試してみます。
- dell_OK
- ベストアンサー率13% (766/5720)
・親要素中に要素を追加するコードのようですが、<h2>確認画面</h2>を意味しているのでしょうか? そうです。 ・参考サイトを見ると末尾に追加されると書いてあり考えていることと異なるのですがどちらが正しいのでしょうか? 末尾に間違いありません。 confirm_area.appendChild(h); のあとで、さらに末尾に、 confirm_area.appendChild(form); で<form>を追加しています。 ・こちらのコードは入力画面の const opt = {} でまとめられているコードと同じ機能だと思うのですが、まとめずに使う事は可能でしょうか? そうですね。 同じ機能のようです。 95行目はなくしてください。 96行目もなくしていいかも知れません。 form.enctype = "multipart/form-data"; と同じことを opt に入れてしまえばいいような気がします。 ・非同期通信でサーバーにfetch を使って送る際のセキュリティ対策に必要なコードをsample.phpに追加したい場合入力画面と確認画面で2度必要だと思われますでしょうか?非同期通信を行うたびに実装が必要なものではないかと考えております… これがなぜセキュリティ対策になるのか私はわかっていません。 ですが、そうですね、送信する限りにおいて両方に必要だと思います。
補足
回答ありがとうございます、理解することが出来ました。
- dell_OK
- ベストアンサー率13% (766/5720)
サーバー側のコードがなかったですね。 サンプルはこんな感じのものです。 ----functions.php function bbs_quest_input() { $message = $_POST['message']; $namae = $_POST['namae']; $stamp = $_POST['stamp']; $error = []; if (empty($message)) { $error[] = 'コメントを入力してください'; } if (empty($namae)) { $error[] = '名前を入力してください'; } if (empty($stamp)) { $error[] = 'スタンプを選択してください'; } $result = []; if (empty($error)) { $result['error'] = ''; $result['namae'] = $namae; $result['message'] = $message; $result['stamp'] = $stamp; } else { $result['error'] = $error; } header('Content-type: application/json; charset=UTF-8'); echo json_encode($result); exit; } add_action('wp_ajax_bbs_quest_input', 'bbs_quest_input'); add_action('wp_ajax_nopriv_bbs_quest_input', 'bbs_quest_input'); function bbs_quest_confirm() { global $wpdb; $sql = 'INSERT INTO sortable(message,namae,stamp,ip) VALUES(%s,%s,%d,%s)'; $message = $_POST['message']; $namae = $_POST['namae']; $stamp = $_POST['stamp']; $ip = $_SERVER['REMOTE_ADDR']; $query = $wpdb->prepare($sql, $message, $namae, $stamp, $ip); $query_result = $wpdb->query($query); $result = []; if (false === $query_result) { $result['error'] = '登録できませんでした'; } else { $result['error'] = ''; $result['message'] = $message; $result['namae'] = $namae; $result['stamp'] = $stamp; } header('Content-type: application/json; charset=UTF-8'); echo json_encode($result); exit; } add_action('wp_ajax_bbs_quest_confirm', 'bbs_quest_confirm'); add_action('wp_ajax_nopriv_bbs_quest_confirm', 'bbs_quest_confirm'); ----
補足
回答ありがとうございます、dell_okさんに作成頂いたコードで分からないところがあるので教えて頂きたいです。 ①sample.phpの93行目のconfirm_area.appendChild(h); //特定の親要素の中に要素を追加するためのメソッド 親要素中に要素を追加するコードのようですが、<h2>確認画面</h2>を意味しているのでしょうか? 参考サイトを見ると末尾に追加されると書いてあり考えていることと異なるのですがどちらが正しいのでしょうか? ※参考サイト https://www.sejuku.net/blog/49970 ②sample.phpの95行目のform.method = "post"; //まとめずに使う事は可能なのだろうか こちらのコードは入力画面の const opt = {} でまとめられているコードと同じ機能だと思うのですが、まとめずに使う事は可能でしょうか? ③single-complete.phpの139行目の<?php wp_nonce_field( 'enquiry-message', '_wpnonce', false ); ?> 非同期通信でサーバーにfetch を使って送る際のセキュリティ対策に必要なコードをsample.phpに追加したい場合入力画面と確認画面で2度必要だと思われますでしょうか?非同期通信を行うたびに実装が必要なものではないかと考えております… ※最新コード https://wandbox.org/permlink/fypPcpYc4mCGaweC
- dell_OK
- ベストアンサー率13% (766/5720)
・268行目からのコードで入力画面と同じものを表示させるような形になるのでしょうか? そうですね。 ですが、私が作ったこのコードはよくありません。 確認画面はフォームになっていないので送信できないからです。 先日のサンプルのコードを見てもらった方がいいと思います。 ブラウザで適当な場所を右クリックして「ページのソースを見る」で見てください。 http://oksample.starfree.jp/%E8%B3%AA%E5%95%8F%E3%81%99%E3%82%8B/ 確認画面用と結果表示用のdivがあります。 ---- <div id="confirm_area"></div> <div id="result_area"></div> ---- 確認画面のフォームや結果表示はJavaScriptで動的に作成しています。 のちのちのことですが、結果表示は、回答No.20に書いたように、一覧に挿入するようになると思うのでこのdivは別の場所に別の方法で記述することになってくると思います。
- dell_OK
- ベストアンサー率13% (766/5720)
・入力画面に戻るボタンについてブラウザの histry.back(=Ctrl + ←)も有効ではないかとアドバイス頂きました。 非同期通信、と言うか、画面遷移(URLが変化)していないので、ブラウザの戻るは使えないと思います。 私のサンプルで試していただくとわかると思いますが、ひとつ前のURLに戻ってしまうので、入力画面には戻れないと思います。 ・サーバ側でのチェックを行うのではないかと別の方からご指摘いただきました。 なるほどですね。 私が勘違いしていたことがありました。 input要素はブラウザの開発モードで値を変更できる、と言うことについてです。 変更できてしまうと、確認画面のフォームの内容は、その前にチェックをしても改ざんされてしまうため意味がない、と思っていました。 ですが、変更できるのはvalueが指定されていないinput要素で、valueを設定したinput要素の場合は変更できないようでした。 なので、入力画面からチェックした内容を確認画面に反映させた場合は大丈夫そうです。
補足
回答ありがとうございます、URLが変更されていなければブラウザの戻るは使えないのですね… 入力画面から確認画面に非同期通信無しで表示と非表示を切り替える方法は可能なようです。 最新コードで前回考えていたコードと組み合わせて、入力画面と確認画面を切り替え、確認画面からFetch APIを使い非同期通信でデーベースに送るように考えてみたのですが、268行目からのコードで入力画面と同じものを表示させるような形になるのでしょうか? <div id="result"> <p id="result_namae"></p> <p id="result_message"></p> <input type="radio" id="result_stamp"><label for="result_stamp"></label> </div> ※最新コード(sample.php) https://wandbox.org/permlink/aNn2rxBWoaoypMPy
- dell_OK
- ベストアンサー率13% (766/5720)
と思いましたが、自分の投稿だけ表示しても、機能的に不足している気がしてきました。 その人が投稿している最中に、他の人が投稿したものが表示されないからです。 回答一覧すべてを表示しなおすとか、前回表示した時以降に投稿されたものを表示するとか、した方がいいような気がします。
補足
回答ありがとうございます、dell_okさんにお伝えしていた、入力から確認と確認からサーバーに送信する際に非同期通信を2度行う方法の明確な理由についてお聞きしていたのですが、サーバ側でのチェックを行うのではないかと別の方からご指摘いただきました。入力画面から確認画面に非同期通信無しで表示と非表示を切り替える方法もセキュリティ上可能か追加でお聞きしております。 入力画面に戻るボタンについてブラウザの histry.back(=Ctrl + ←)も有効ではないかとアドバイス頂きました。 ・同じ内容の連投チェック ・禁止用語などのチェック ・荒しなどの対策 ・セッションを利用しているなら、そのチェック
- dell_OK
- ベストアンサー率13% (766/5720)
・入力画面に戻る際に入力した内容が保存されているところを不思議に思ったのですが、セッションで値を引き継いでいるのでしょうか? 方法は質問者さまと同じです。 入力画面のフォームの表示非表示を切り替えているだけなので、入力内容はそのまま残っています。 ・コメントを送信後に表示画面で入力画面と同じものを表示することは可能でしょうか? 確認画面は出さないで、そのかわりその内容を回答一覧に挿入する感じになると思います。
補足
回答ありがとうございます、なるほど表示と非表示を切り替えた場合に入力内容を保持することが可能という事になるんですね。 確認画面から送信後にリダイレクトする形で入力画面に戻すイメージで考えておりました…
補足
Q.ローカルストレージなどに保存しないと入力内容が消えるのではないかというアドバイス 必ず消えるとかでないのなら、消えた場合に入力画面に戻るようにして、再入力してもらえばいいと思います。 消えないと言うか消えてもいいと言うか、セッションならこれは問題になりません。 確認画面から結果画面へ行く時は、「確認画面から結果画面へ行くよ」と言う情報しか(改ざんされたデータがない)サーバーに送信しないので安全です。 A.回答ありがとうございます、dell_ok さんと同じように考えている方もおられるようで消えないかもしれません… 条件で消えるようであれば再入力してもらう方法がよさそうですね。 非同期通信という事で画面が還移する場合と違うのではないかと心配になっておりました。データをチェックして対策すれば問題ということでコードを考えていきます。