質問編集履歴

3 誤字

pecchan

pecchan score 269

2019/03/14 10:19  投稿

【CakePHP、JavaScript】ポスト送信時スクリプトを挟むと、なぜ遷移が変わってしまうのでしょうか?
cakephp(2.7.8)
PHP 5.6
MySQL 5.6
お問い合わせページを作りました。
1.入力画面
2.入力内容の確認画面
3.結果画面
1の入力画面にてお問い合わせ内容を入力、
2の確認画面にて送信するとメール送信し、
3の結果画面に遷移して終わりです。
ここで、2の確認画面にて送信ボタンが二重ポストできるため、
昨日こちらで色々と教えていただきスクリプトで制御を入れました。
[【jQuery】2重ポスト禁止したい](https://teratail.com/questions/178992)
ところが、
2の確認画面にて送信ボタンを押すと、
3の結果画面ではなく、1の入力画面に遷移してしまうようになりました。
※以前はちゃんと3の結果画面に遷移してました
そのため、ずっと入力画面と確認画面の永久ループです(*_*)?
?????
これは、内部でどういうことが起こっているのでしょう?
何が起きているのかだけでも教えていただければ幸いです。
宜しくお願い致します。
コントローラ
```PHP
<?php
App::uses('User', 'Model');
class ContactsController extends AppController {
   public $components = array('Session');
   public function contact()
   {
       
       $this->set('title', 'お問い合せ');
       if (!$this->request->is('post') || !$this->request->data) {
           return;
       }
       $this->Contact->set($this->request->data);
       if (!$this->Contact->validates()) {
           $this->Session->setFlash('入力内容に不備があります。');
           return;
       }
       switch ($this->request->data['confirm']) {
           //確認画面
           case 'confirm':
               //トークン生成
               $tkn = $this->_getToken();
                   
               //トークンをセッションに保存 
               $this->Session->write('contact_token', $tkn);
               
               //トークンをviewに渡す
               $this->set('contact_token', $tkn);
               $this->render('contact_confirm');
               break;
           //送信後画面
           case 'send':
               //不正アクセス、二重ポスト対策
               if($this->request->data['Contact']['contact_token'] == null ||
                   $this->request->data['Contact']['contact_token'] != $this->Session->read('contact_token'))
               {
                   
               
                   //セッションクリア
                   $this->Session->destroy();
                   
                   //トップページへ
                   header('Location:../');
                   exit();
                   
               }
               $this->sendContact($this->request->data['Contact']);
               
               $this->render('email_sent');
               
               break;
       }
       
   }
   private function sendContact($content)
   {
       App::uses('CakeEmail', 'Network/Email');
       $email = new CakeEmail('contact');
       
       $email->to($content['email']);
       $email->subject('【test】お問い合わせを受け付けました');
       $email->send();
   }
   /*
   *
   * トークンを作成し返却する
   */
   private function _getToken()
   {
       return md5(uniqid().mt_rand());
   }
}
```
ビュー
1.入力画面
```html
<div class="container">
   <div class="row">
       <div class="col col-md-12">
           <div class="col-md-6 form-login ">
               <?php
                   //echo $this->Session->flash();
                   echo $this->Form->create('Contact');
                   echo $this->Form->input('name', array(
                       'type' => 'text',
                       'label' => 'お名前',
                       'maxlength' => 255,
                       'value' => $User['User']['name'],
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->input('email', array(
                       'type' => 'email',
                       'label' => 'メールアドレス',
                       'maxlength' => 255,
                       'value' => $User['User']['email'],
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->input('body', array(
                       'type' => 'textarea',
                       'label' => '本文',
                       'maxlength' => 3000,
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->button('確認する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'value' => 'confirm',
                       'class' => 'btn btn-primary btn-md'
                       )
                   );
                   echo $this->Form->end();
               ?>
           </div>
       </div>
   </div>
</div><!-- container end -->
```
ビュー
2.確認画面
```html
<div class="container">
   <div class="row">
       <div class="col col-md-12">
           <div class="col-md-6 form-login">
               <dl>   
                   <dt>お名前</dt>
                   <dd><?php echo $this->request->data['Contact']['name']; ?></dd>
                   <br>
                   <dt>メールアドレス</dt>
                   <dd><?php echo $this->request->data['Contact']['email']; ?></dd>
                   <br>
                   
                   <dt>お問い合せ本文</dt>
                   <dd><?php echo nl2br($this->request->data['Contact']['body']); ?></dd>
               </dl>
                   
               <?php
                   echo $this->Form->create('Contact');
                   
                   echo $this->Form->hidden('contact_token', array('value' => $contact_token));
                   foreach ($this->request->data['Contact'] as $name => $val) {
                        echo $this->Form->hidden($name, array('value' => $val));
                   }
                   echo $this->Form->button('修正する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'value' => 'revise',
                       'class' => 'btn btn-primary btn-md'
                   ));
                   echo $this->Form->button('送信する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'id' => 'test',
                       'value' => 'send',
                       'class' => 'btn btn-primary btn-md'
                   ));
                   echo $this->Form->end();
               ?>
           </div>
       </div>
   </div>
</div><!-- container end -->
```
ビュー
3.結果画面
```html
<div class="container">
   <div class="row">
       <div class="col-md-6">
           <!-- <?php echo $this->Session->flash(); ?> -->
           <h4>お問い合わせを受け付けました</h4>
           <?php echo $this->Html->link('トップページへ', '../'); ?>
       </div>
   </div>
</div><!-- container end -->
```
スクリプト
```javascript
$(function () {
    $('form').submit(function () {
       //alert("test");
       $("#test", this).prop("disabled", true);
       
   });
});
```
【翌日追記】
翌日調べて分かったことを追記致します。
スクリプト経由でコントローラへ飛ぶと、コントローラのswitch文の部分、
$this->request->data['confirm']の値がNULLになっておりました。
そのためcaseで条件に引っかからず処理が下まで流れてました。
スクリプト経由せずコントローラへ飛ぶ場合、
$this->request->data['confirm']には、前画面(確認画面)からの来たよ。
$this->request->data['confirm']には、「前画面(確認画面)から来たよ。」
という意味での値'send'が入っております。
このため、case NULL:の時(スクリプト経由時)は、case 'send'と同じ処理を通るようにしてあげれば、とりあえずは、意図したように動きはしますが、NULLになるのは現象であって根本的な原因ではないと考えております。
なぜスクリプト経由だと、
$this->request->data['confirm']がNULLになってしまうのでしょう?
Webプログラム独学で初心者のため、これが「普通」、「当たり前の動作」なのかどうかも分からないでいます。
  • JavaScript

    25601 questions

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

  • CakePHP

    2761 questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • jQuery

    9988 questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

2 分かった所までを追記

pecchan

pecchan score 269

2019/03/14 10:18  投稿

【CakePHP、JavaScript】ポスト送信時スクリプトを挟むと、なぜ遷移が変わってしまうのでしょうか?
cakephp(2.7.8)
PHP 5.6
MySQL 5.6
お問い合わせページを作りました。
1.入力画面
2.入力内容の確認画面
3.結果画面
1の入力画面にてお問い合わせ内容を入力、
2の確認画面にて送信するとメール送信し、
3の結果画面に遷移して終わりです。
ここで、2の確認画面にて送信ボタンが二重ポストできるため、
昨日こちらで色々と教えていただきスクリプトで制御を入れました。
[【jQuery】2重ポスト禁止したい](https://teratail.com/questions/178992)
ところが、
2の確認画面にて送信ボタンを押すと、
3の結果画面ではなく、1の入力画面に遷移してしまうようになりました。
※以前はちゃんと3の結果画面に遷移してました
そのため、ずっと入力画面と確認画面の永久ループです(*_*)?
?????
これは、内部でどういうことが起こっているのでしょう?
何が起きているのかだけでも教えていただければ幸いです。
宜しくお願い致します。
コントローラ
```PHP
<?php
App::uses('User', 'Model');
class ContactsController extends AppController {
   public $components = array('Session');
   public function contact()
   {
       
       $this->set('title', 'お問い合せ');
       if (!$this->request->is('post') || !$this->request->data) {
           return;
       }
       $this->Contact->set($this->request->data);
       if (!$this->Contact->validates()) {
           $this->Session->setFlash('入力内容に不備があります。');
           return;
       }
       switch ($this->request->data['confirm']) {
           //確認画面
           case 'confirm':
               //トークン生成
               $tkn = $this->_getToken();
                   
               //トークンをセッションに保存 
               $this->Session->write('contact_token', $tkn);
               
               //トークンをviewに渡す
               $this->set('contact_token', $tkn);
               $this->render('contact_confirm');
               break;
           //送信後画面
           case 'send':
               //不正アクセス、二重ポスト対策
               if($this->request->data['Contact']['contact_token'] == null ||
                   $this->request->data['Contact']['contact_token'] != $this->Session->read('contact_token'))
               {
                   
               
                   //セッションクリア
                   $this->Session->destroy();
                   
                   //トップページへ
                   header('Location:../');
                   exit();
                   
               }
               $this->sendContact($this->request->data['Contact']);
               
               $this->render('email_sent');
               
               break;
       }
       
   }
   private function sendContact($content)
   {
       App::uses('CakeEmail', 'Network/Email');
       $email = new CakeEmail('contact');
       
       $email->to($content['email']);
       $email->subject('【test】お問い合わせを受け付けました');
       $email->send();
   }
   /*
   *
   * トークンを作成し返却する
   */
   private function _getToken()
   {
       return md5(uniqid().mt_rand());
   }
}
```
ビュー
1.入力画面
```html
<div class="container">
   <div class="row">
       <div class="col col-md-12">
           <div class="col-md-6 form-login ">
               <?php
                   //echo $this->Session->flash();
                   echo $this->Form->create('Contact');
                   echo $this->Form->input('name', array(
                       'type' => 'text',
                       'label' => 'お名前',
                       'maxlength' => 255,
                       'value' => $User['User']['name'],
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->input('email', array(
                       'type' => 'email',
                       'label' => 'メールアドレス',
                       'maxlength' => 255,
                       'value' => $User['User']['email'],
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->input('body', array(
                       'type' => 'textarea',
                       'label' => '本文',
                       'maxlength' => 3000,
                       'class' => 'form-control input-sm chat-input'
                       )
                   );
                   echo $this->Form->button('確認する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'value' => 'confirm',
                       'class' => 'btn btn-primary btn-md'
                       )
                   );
                   echo $this->Form->end();
               ?>
           </div>
       </div>
   </div>
</div><!-- container end -->
```
ビュー
2.確認画面
```html
<div class="container">
   <div class="row">
       <div class="col col-md-12">
           <div class="col-md-6 form-login">
               <dl>   
                   <dt>お名前</dt>
                   <dd><?php echo $this->request->data['Contact']['name']; ?></dd>
                   <br>
                   <dt>メールアドレス</dt>
                   <dd><?php echo $this->request->data['Contact']['email']; ?></dd>
                   <br>
                   
                   <dt>お問い合せ本文</dt>
                   <dd><?php echo nl2br($this->request->data['Contact']['body']); ?></dd>
               </dl>
                   
               <?php
                   echo $this->Form->create('Contact');
                   
                   echo $this->Form->hidden('contact_token', array('value' => $contact_token));
                   foreach ($this->request->data['Contact'] as $name => $val) {
                        echo $this->Form->hidden($name, array('value' => $val));
                   }
                   echo $this->Form->button('修正する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'value' => 'revise',
                       'class' => 'btn btn-primary btn-md'
                   ));
                   echo $this->Form->button('送信する', array(
                       'type' => 'submit',
                       'name' => 'confirm',
                       'id' => 'test',
                       'value' => 'send',
                       'class' => 'btn btn-primary btn-md'
                   ));
                   echo $this->Form->end();
               ?>
           </div>
       </div>
   </div>
</div><!-- container end -->
```
ビュー
3.結果画面
```html
<div class="container">
   <div class="row">
       <div class="col-md-6">
           <!-- <?php echo $this->Session->flash(); ?> -->
           <h4>お問い合わせを受け付けました</h4>
           <?php echo $this->Html->link('トップページへ', '../'); ?>
       </div>
   </div>
</div><!-- container end -->
```
スクリプト
```javascript
$(function () {
    $('form').submit(function () {
       //alert("test");
       $("#test", this).prop("disabled", true);
       
   });
});
```
```
【翌日追記】
翌日調べて分かったことを追記致します。
スクリプト経由でコントローラへ飛ぶと、コントローラのswitch文の部分、
$this->request->data['confirm']の値がNULLになっておりました。
そのためcaseで条件に引っかからず処理が下まで流れてました。
スクリプト経由せずコントローラへ飛ぶ場合、
$this->request->data['confirm']には、前画面(確認画面)からの来たよ。
という意味での値'send'が入っております。
このため、case NULL:の時(スクリプト経由時)は、case 'send'と同じ処理を通るようにしてあげれば、とりあえずは、意図したように動きはしますが、NULLになるのは現象であって根本的な原因ではないと考えております。
なぜスクリプト経由だと、
$this->request->data['confirm']がNULLになってしまうのでしょう?
Webプログラム独学で初心者のため、これが「普通」、「当たり前の動作」なのかどうかも分からないでいます。
  • JavaScript

    25601 questions

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

  • CakePHP

    2761 questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • jQuery

    9988 questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

1 タイトル変更

pecchan

pecchan score 269

2019/03/13 17:18  投稿

【CakePHP、JavaScript】ポスト送信時スクリプトを挟むと、遷移が変わってしまうのでしょうか?
【CakePHP、JavaScript】ポスト送信時スクリプトを挟むと、なぜ遷移が変わってしまうのでしょうか?
cakephp(2.7.8)
PHP 5.6
MySQL 5.6
お問い合わせページを作りました。
1.入力画面
2.入力内容の確認画面
3.結果画面
1の入力画面にてお問い合わせ内容を入力、
2の確認画面にて送信するとメール送信し、
3の結果画面に遷移して終わりです。
ここで、2の確認画面にて送信ボタンが二重ポストできるため、
昨日こちらで色々と教えていただきスクリプトで制御を入れました。
[【jQuery】2重ポスト禁止したい](https://teratail.com/questions/178992)
ところが、
2の確認画面にて送信ボタンを押すと、
3の結果画面ではなく、1の入力画面に遷移してしまうようになりました。
※以前はちゃんと3の結果画面に遷移してました
そのため、ずっと入力画面と確認画面の永久ループです(*_*)?
?????
これは、内部でどういうことが起こっているのでしょう?
何が起きているのかだけでも教えていただければ幸いです。
宜しくお願い致します。
コントローラ
```PHP
<?php
App::uses('User', 'Model');
class ContactsController extends AppController {
public $components = array('Session');
public function contact()
{
$this->set('title', 'お問い合せ');
if (!$this->request->is('post') || !$this->request->data) {
return;
}
$this->Contact->set($this->request->data);
if (!$this->Contact->validates()) {
$this->Session->setFlash('入力内容に不備があります。');
return;
}
switch ($this->request->data['confirm']) {
//確認画面
case 'confirm':
//トークン生成
$tkn = $this->_getToken();
//トークンをセッションに保存 
$this->Session->write('contact_token', $tkn);
//トークンをviewに渡す
$this->set('contact_token', $tkn);
$this->render('contact_confirm');
break;
//送信後画面
case 'send':
//不正アクセス、二重ポスト対策
if($this->request->data['Contact']['contact_token'] == null ||
$this->request->data['Contact']['contact_token'] != $this->Session->read('contact_token'))
{
//セッションクリア
$this->Session->destroy();
//トップページへ
header('Location:../');
exit();
}
$this->sendContact($this->request->data['Contact']);
$this->render('email_sent');
break;
}
}
private function sendContact($content)
{
App::uses('CakeEmail', 'Network/Email');
$email = new CakeEmail('contact');
$email->to($content['email']);
$email->subject('【test】お問い合わせを受け付けました');
$email->send();
}
/*
*
* トークンを作成し返却する
*/
private function _getToken()
{
return md5(uniqid().mt_rand());
}
}
```
ビュー
1.入力画面
```html
<div class="container">
<div class="row">
<div class="col col-md-12">
<div class="col-md-6 form-login ">
<?php
//echo $this->Session->flash();
echo $this->Form->create('Contact');
echo $this->Form->input('name', array(
'type' => 'text',
'label' => 'お名前',
'maxlength' => 255,
'value' => $User['User']['name'],
'class' => 'form-control input-sm chat-input'
)
);
echo $this->Form->input('email', array(
'type' => 'email',
'label' => 'メールアドレス',
'maxlength' => 255,
'value' => $User['User']['email'],
'class' => 'form-control input-sm chat-input'
)
);
echo $this->Form->input('body', array(
'type' => 'textarea',
'label' => '本文',
'maxlength' => 3000,
'class' => 'form-control input-sm chat-input'
)
);
echo $this->Form->button('確認する', array(
'type' => 'submit',
'name' => 'confirm',
'value' => 'confirm',
'class' => 'btn btn-primary btn-md'
)
);
echo $this->Form->end();
?>
</div>
</div>
</div>
</div><!-- container end -->
```
ビュー
2.確認画面
```html
<div class="container">
<div class="row">
<div class="col col-md-12">
<div class="col-md-6 form-login">
<dl>
<dt>お名前</dt>
<dd><?php echo $this->request->data['Contact']['name']; ?></dd>
<br>
<dt>メールアドレス</dt>
<dd><?php echo $this->request->data['Contact']['email']; ?></dd>
<br>
<dt>お問い合せ本文</dt>
<dd><?php echo nl2br($this->request->data['Contact']['body']); ?></dd>
</dl>
<?php
echo $this->Form->create('Contact');
echo $this->Form->hidden('contact_token', array('value' => $contact_token));
foreach ($this->request->data['Contact'] as $name => $val) {
echo $this->Form->hidden($name, array('value' => $val));
}
echo $this->Form->button('修正する', array(
'type' => 'submit',
'name' => 'confirm',
'value' => 'revise',
'class' => 'btn btn-primary btn-md'
));
echo $this->Form->button('送信する', array(
'type' => 'submit',
'name' => 'confirm',
'id' => 'test',
'value' => 'send',
'class' => 'btn btn-primary btn-md'
));
echo $this->Form->end();
?>
</div>
</div>
</div>
</div><!-- container end -->
```
ビュー
3.結果画面
```html
<div class="container">
<div class="row">
<div class="col-md-6">
<!-- <?php echo $this->Session->flash(); ?> -->
<h4>お問い合わせを受け付けました</h4>
<?php echo $this->Html->link('トップページへ', '../'); ?>
</div>
</div>
</div><!-- container end -->
```
スクリプト
```javascript
$(function () {
$('form').submit(function () {
//alert("test");
$("#test", this).prop("disabled", true);
});
});
```
  • JavaScript

    25601 questions

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

  • CakePHP

    2761 questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • jQuery

    9988 questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る