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

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

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

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

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

2回答

2346閲覧

ページ遷移を行なった後、再度POSTリクエストを行いたい

study_111

総合スコア82

Django

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

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/07/07 03:21

編集2020/07/07 06:50

前提・実現したいこと

現状、index.htmlにて、formからURLを入力し、送信を行うと、「http://127.0.0.1:8000/polls/check/」に遷移します。しかし、そこでリロードをかけると以下のエラーが発生してしまいます。

Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8000/polls/check/ Using the URLconf defined in wp_tool.urls, Django tried these URL patterns, in this order: polls/ [name='index'] polls/ <int:question_oo>/ [name='detail'] polls/ check [name='check'] admin/ The current path, polls/check/, didn't match any of these. You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

こちら、GETでのアクセスとなっているのですが、こちらを「POST」リクエストとして、再度formからのリクエストとして、制御したいと考えています。

該当のソースコード

以下は、index.htmlです。

html

1{% load static %} 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"/> 7 <link rel="stylesheet" type="text/css" href="{% static 'polls/css/style.css' %}"> 8 <title>demo</title> 9</head> 10<body> 11 <div class="loader hidden" id="loading">Loading...</div> 12 <form id="form" action="{% url 'polls:check' %}" method="post"> 13 {% csrf_token %} 14 <input type="url" name="check_url" placeholder="http://example.com"/> 15 <!-- <button type="submit" name="check" value="send">送信</button> --> 16 <button type="button" onclick="sendData()">送信</button> 17 </form> 18 <script src="{% static 'polls/js/app.js' %}"></script> 19</body> 20</html>

以下は、check.htmlです。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p>check.htmlです</p> <p>{{ alert_msg.err_test }}</p> </body> </html>

以下は、views.pyです。

def index(request): return render(request,'polls/index.html') def check(request): if request.method == "GET": return redirect("polls:index") input_url = request.POST['check_url'] print(input_url) #諸々の処理 return render(request,'polls/check.html',{'alert_msg':alert_msg})

以下は、app.jsです。

function showElement(e) { e.classList.remove("hidden"); } function hideElement(e) { e.classList.add("hidden"); } async function sendData() { // ローディング画面を表示する showElement(document.getElementById("loading")); //formデータを取得 let formElem = document.getElementById("form") // console.log(formElem) let formUrl = formElem.action; let formData = new FormData(formElem); // console.log(formData) let response = await fetch(formUrl, { method: 'POST', body: formData }); // ローディング画面を隠します hideElement(document.getElementById("loading")); if(response.ok){ //成功の場合の処理 console.log(response) document.open(); document.write(await response.text()); document.close(); // 前のページへ正しく戻れるようページ歴史に追加する history.pushState(null, "", "/polls/check/"); }else{ //失敗の場合の処理 } }

追記です
現状、修正を行いたい点がもう一つあります。

以下は、http://127.0.0.1:8000/polls/の画面になります。
イメージ説明
こちらのindex.htmlからformに値を入力し、送信ボタンを押した際には、以下の画面が表示されます。

イメージ説明
こちらのアドレスはhttp://127.0.0.1:8000/polls/check/です。しかし、ブラウザの戻るボタンを押した際にもこちらのcheck.htmlが表示されてしまいます。
イメージ説明
上記画像は、戻るボタンを押した際の画面ですが、http://127.0.0.1:8000/polls/check/で表示されていた内容と同じ内容が表示されてしまっている状況です。

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

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

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

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

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

YufanLou

2020/07/07 05:40

def check(request): if request.method == "GET": return redirect("polls:index") ここを見ると、/polls/checkでリロードしたらindexへリダイレクトされるはずです。どうして404が出ましたか?他のエラーがありましたか?
study_111

2020/07/07 06:11

チェック頂きまして、ありがとうございます。 すみません。エラー内容の方、省略してしまっていた部分がありました為、すべて元のエラー文に追記致しました。
YufanLou

2020/07/07 06:19

追記ありがとうございました。 問題は末尾のスラッシュです。 polls/ check [name='check'] このルートの末尾にスラッシュがないので、 /polls/check/ と末尾スラッシュがあるURLでリクエストしたら404が出ます。
study_111

2020/07/07 06:27 編集

教えて下さりまして、ありがとうございます。 urls.pyの部分を「path('check/', views.check, name='check'),」こちらのように、変更しましたらエラーを削除することが出来ました。
study_111

2020/07/07 06:36 編集

何度も、お手数をおかけして申し訳ないのですが、実は後、2点程どうしても修正したいポイントがあります。 そこの部分というのは、本質問にありますリロードした際に「POST」リクエストとしたいといった部分と、もう一点は「http://127.0.0.1:8000/polls/check/」このページにPOSTで遷移した際に、ブラウザの戻るボタンを押しても「check.html」の内容が表示されたままであるという点です。 こちら、2点目に関しましては、質問内容の方に詳しく記載させて頂きたいと存じます。
guest

回答2

0

ページ遷移を行なった後

ページを自動遷移する基本技法でもあるリダイレクト処理は試されたでしょうか。

index.html でフォーム入力し、check.html が表示されてすぐに 再度 index.html を表示するという対応になります。

  1. index.html (フォームを表示するページ)

input[type=submit]form[action] の示すURLにPOST要求
2. check.html (POSTされたデータを処理後に表示される)
サーバーで入力値を保存するなりして、終わった合図としてページが表示されている

方法としては、3つあります。

  1. check.htmlを応答するのではなく HTTPステータス 301 を応答して index.html にリダイレクトする
  2. check.htmlの load イベントなどに location.href="path/to/index.html" を仕込む
  3. check.htmlに meta[name="refresh"][content="5;http://example.com/path/to/index.html/"]

(SEO的に待機時間0は非推奨)


Single Page Application であれば YufanLou さんの回答が参考になるはずでした。

追記)

今回の場合は注意メッセージをアラートとして表示させずにformの内容の再送(POSTリクエスト)を行おうと考えています。(コメントより)

ページ遷移による実装ですと、古い「メール送信CGI」の実装事例が近いように思います。

  1. form.html (入力フォーム)

POSTすると、メール送信せず、確認ページに入力されたデータを埋め込んだフォームのページを応答
2. check.html (確認ページ+入力フォーム:フィールドは必要に応じてhidden)
2回目のPOSTでメール送信。
3. thanks.html (リダイレクト)

※問い合わせ内容のDBへの保存はメールを送信する処理の直前(または直後)に記述。

投稿2020/07/07 21:34

編集2020/07/08 04:12
AkitoshiManabe

総合スコア5434

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

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

study_111

2020/07/08 03:51 編集

ご回答ありがとうございます。 > index.html でフォーム入力し、check.html が表示されてすぐに 再度 index.html を表示するという対応になります。 こちらですが、check.htmlが表示されてから、自動でリダイレクトをかけるというよりかは、手動でリロードボタンを押した際に、たまにブラウザにアラートが出る「formの内容を再送しますか?」のメッセージが出力された後、OKボタンを押すと再度formの内容がPOSTリクエストとして再送される処理を実装したいと考えています。 ですが、今回の場合は注意メッセージをアラートとして表示させずにformの内容をただ再送(POSTリクエスト)する形でいこうかと考えています。
AkitoshiManabe

2020/07/08 04:25 編集

> たまに ブラウザの再送信確認ダイアログは POST要求に応答されたページでリロードすると必ず表示されます。 多重送信の原因になることから、送信後にリダイレクトを利用する方法が使われるようになっています。 ページ遷移の流れにおいて「確認ページを挟む方法」を追記しましたので参考にしてみてください。
study_111

2020/07/08 07:33 編集

ご追記頂きまして、ありがとうございます。 > 多重送信の原因になることから、送信後にリダイレクトを利用する方法が使われるようになっています。 こちらなのですが、今回の場合、問い合わせフォームの送信というよりかは、formから入力された値を元にプログラム側に処理を飛ばし、結果を表示するのみの形で考えておりました。 具体的には、こちらのサイトのように実装したいと考えております。
AkitoshiManabe

2020/07/08 06:57

> 具体的には~のように実装したい 似た実装にしたい場合は、検証ツールで、「どのように実装されているのか」を調査します。 ざっと確認すると、「フォーム部分は form#scanform[method=GET] であり、 javascriptで onSubmitScanForm() 関数(L38 で読まれた /scripts.min.js内に定義されている)を実行するSPA」実装のようですので、私の回答ではお力になれないようです。
study_111

2020/07/08 07:35 編集

ご返信ありがとうございます。 自分でもリンク先を検証ツールで確認するなどし、調べてみます。 ご親切にご助言頂きまして、ありがとうございました。
guest

0

History API のpushStateを用いて新たなURLを歴史に加えてから、バックの時はindexページを表示したい場合、window.onpopstatewindow.locationdocument.locationで書き換えしてください。

javascript

1window.onpopstate = function(event) { 2 window.location.assign(document.location); 3}

追記:問題文のコードはcheck.htmlindex.htmlを書き換えたので、上記のJavaScriptをcheck.htmlに入れてください。

リロードについて追記:

/poll/check でリロードで form データ再送するのを実装します。
まず、どこかで form データを保存しなければならない。History API で歴史 state に form データを保存できます。

javascript

1// app.js 2// ... 3async function sendDataOnLoad() { 4 //歴史state存在しなかったら中止 5 if (!history.state) return; 6 //歴史stateからformデータを取得 7 let formData = history.state.formData; 8 let response = await fetch(formUrl, { 9 method: 'POST', 10 body: formData 11 }); 12 if(response.ok){ 13 //成功の場合の処理 14 console.log(response) 15 document.open(); 16 document.write(await response.text()); 17 document.close(); 18 }else{ 19 //失敗の場合の処理 20 } 21} 22window.onload = sendDataOnLoad;

サーバーサイドでリダイレクトしたらこのコードを動作しなくなるかもしれないので、Pythonをこう変わります:

python

1// views.py 2def check(request): 3 4 if request.method == "GET": 5 return render(request, 'polls/index.html') 6 # ...

けど、直接にこう実装したら、formデータを送信して、/polls/checkをロードして、formデータを送信して、/polls/checkをロードして…という無限ループになりそうです。

未完成ですが、参考になれたら幸いです。

投稿2020/07/07 07:39

編集2020/07/07 11:23
YufanLou

総合スコア464

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

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

study_111

2020/07/07 08:45 編集

ご回答ありがとうございます。 度々、すみません。 ご提示頂きましたコードをapp.jsの先頭へ追記したのですが、戻るボタンを押すと、現状変わらず、check.htmlの内容が表示されたままの状態です...
study_111

2020/07/07 09:00

check.htmlにjavascriptファイルを読み込んでいないことが原因でした... check.htmlへjsファイルのパスを記述しましたら、戻るボタンを押した際に、「index.html」が読み込まれました。
YufanLou

2020/07/07 10:17

ごめんなさい、それを忘れてしまいました。追記しました。
study_111

2020/07/07 10:25 編集

いえ...お世話になっていますし、全然謝らなくて大丈夫です... ご追記頂きありがとうございます。 check.htmlに遷移した際にリロードした場合に、formの内容を再送する形でPOSTリクエストにすることは実際問題厳しいですかね...?
YufanLou

2020/07/07 11:03

いろいろ書き換わらないといけないからちょっと厳しい。
study_111

2020/07/07 11:10

なるほどです...このままで進めることも視野に代替策なども検討してみたいと思います。 ご助言頂きまして、ありがとうございました。
study_111

2020/07/08 01:23 編集

ご追記頂きまして、ありがとうございます。 > まず、どこかで form データを保存しなければならない。 こちらなのですが、sendData関数内で、「history.pushState(formData, "", "/polls/check/");」と行なったのですが、sendDataOnLoad関数内で、「console.log(history.state)」と記載し、POSTリクエストを行なった後、コンソールで確認してみたのですが、値が「null」となってしまい、リロードしても、「index.html」にリダイレクトしてしまっている状況です...
study_111

2020/07/08 01:44

もしかしたらなのですが、sendDataOnLoad内の「formUrl」もどこかで保存する必要がありますでしょうか...?
YufanLou

2020/07/08 07:12

formUrlを保存する必要もありますが、history.stateがnullのままでは保存できませんね。POST使わなくても大丈夫なら、GETを使って、URLにformDataを保存したら、何もしなくてもリロードを越えて保存できます。
YufanLou

2020/07/08 07:31

そして、やはりdocument.writeでdocument全部書き換えたらいろいろ難しくなります。このプロジェクトはなんのためですか?フロントエンドを勉強したいなら、document.writeを使わずに本気でSPAを作るのがおすすめです。バックエンドを勉強したいなら、ローディング画面を一旦置いといて他の機能を開発するのがおすすめです。
study_111

2020/07/08 07:43

> このプロジェクトはなんのためですか? こちらは、仕事の案件で取り組んでいるといった形です。 > document.writeを使わずに本気でSPAを作るのがおすすめです。 自分はjavascriptの経験が浅いのですが、SPAは難易度が高い技術になって来ますでしょうか...? 現状、どのような形でフロント開発を進めて行けば良いか少々悩んでいる状況です...
study_111

2020/07/08 07:45

>POST使わなくても大丈夫なら、GETを使って、URLにformDataを保存したら、何もしなくてもリロードを越えて保存できます。 こちら、参考にさせて頂き、試してみたいと存じます。
YufanLou

2020/07/08 08:23

> SPAは難易度が高い技術になって来ますでしょうか...? JavaScript経験が浅いだとしたらちょっと難しいです。ほぼJavaScriptでやってますから。 仕事の案件にローディング画面の必要がありましたら仕方ありませんが、そうではない場合は別の機能を先に実装して、どのページが遅いなら特別にそのページでローディング画面を実装する方がいいと思います。 必要だとしたら、仕方なくJavaScriptを勉強しSPAを作りましょう。 Vue.js などのフレームワークを用いたら楽になります。
study_111

2020/07/08 11:20

アドバイスありがとうございます。 SPAを調べてみたのですが、JSのみでも出来なくないみたいですが、フレームワークを使用しなければ難しいようですね。 今回、ロード画面の実装を考えた経緯は、プログラム側で処理に時間がかかってしまうこともあり、ロード画面があった方が、UX的に良いかなと判断した形でした。 今回は、ここまで色々と学ばせて頂くことも多かったですし、せっかくなのでVueの学習がてら、SPAでの開発にチャレンジしてみたいとは、考えております。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問