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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

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

JavaScript

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

Q&A

解決済

2回答

7044閲覧

cakePHP3 ajaxの受け渡し

ofuru.no.good

総合スコア15

JSON

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

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

JavaScript

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

0グッド

0クリップ

投稿2018/12/13 04:08

編集2018/12/13 08:38

ControllerでAjaxのpostデータを確認できない。
alertで「通信失敗」が表示されるため、Controllerの$this->request->is('ajax')まで処理できているとは思います。

viewのアコーディオンが開いたとき、IDが***だったら処理されるようになっています。

js

1$(function() { 2 $('#******').on('shown.bs.collapse',function() { 3 4 $.ajax({ 5 url: "https://********/コントローラー名/faqLog", 6 type: "post", 7 dataType: "json", 8 beforeSend: function(xhr){ 9 xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val()); 10 }, 11 contentType: 'application/json', 12 data: {"id" : "situmon"}, 13 }).done(function(response) { 14 if (response.result === 'NG') { 15 alert('保存失敗'); 16 return false; 17 } 18 19 alert('保存成功'); 20 return true; 21 }).fail(function(XMLHttpRequest, textStatus, errorThrown) { 22 alert('\n通信失敗 \nXMLHttpRequest : ' + XMLHttpRequest.status + '\ntextStatus : ' + textStatus + '\nerrorThrown : ' + errorThrown.message +'\n'); 23 }); 24 }); 25

コントローラー

controller

1public function faqLog() 2 { 3 $this->autoRender = false; 4 if ($this->request->is('ajax')) { 5 6 //$id = $this->request; 7 $id = $this->request->getData(['id']); 8 $id = json_encode($id); 9 $this->log(debug($id)); 10 11 if ($id == null) { 12 $this->Flash->boot_error(__('データなし')); 13         return $this->getResponse()->withType('json')->withStringBody(json_encode(['result' => 'OK'])); 14 } 15 16 return $this->getResponse()->withType('json')->withStringBody(json_encode(['result' => 'NG'])); 17 } 18 } 19

補足、
・JSのdataType: "json"を消すとアラートで「保存成功」となるがデータは空。

file
XMLHttpRequest : 200
textStatus : parsererror
errorThrown : Unexpected token < in JSON at position 0

・$this->request で確認したところ
[stream:protected] => Zend\Diactoros\PhpInputStream Object
(
[cache:Zend\Diactoros\PhpInputStream:private] => situmon <-ここにいた!
[reachedEof:Zend\Diactoros\PhpInputStream:private] => 1
[resource:protected] => Resource id #5
[stream:protected] => php://input
)

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

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

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

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

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

m.ts10806

2018/12/13 04:18

何がでしょうか。 >説明不足で申し訳ありません。。。 説明不足を実感されているのでしたら、このコメントの分、要件を書いてもらったほうが見ている方としては大変助かります。 今failの方に入っているのでしたらステータスとかエラーとかレスポンス値をとってconsole.log()に出力して確認したほうが原因追求につながります。
ofuru.no.good

2018/12/13 05:22

補足、JSのdataType: "json"を消して実行するとアラート「保存成功」しますが、データは空です。問題がない場合、console.log()よりもcakeのログに書き込んだほうが良いと思い、console.log()は使っていません。
m.ts10806

2018/12/13 05:28

質問は編集できるので追記してください。failに入る場合はphp側でのエラーが返されていることもありますし、ログ直接確認よりも早いのでデバッグがわりにコンソール出力いれておいても良いと思いますよ。 ケースはすぐには思い浮かばないですがCakeが拾えないエラーが出ていた場合に把握しきれないので、情報取得先は多い方がいいです。
ofuru.no.good

2018/12/13 05:29

failに入る場合にconsole.log()使用してみます。
ofuru.no.good

2018/12/13 06:44

XMLHttpRequest : 200 textStatus : parsererror errorThrown : Unexpected token < in JSON at position 0 が表示されました。
m.ts10806

2018/12/13 06:49

正しいJSON形式の文字列になっていないことが原因ですね。 PHP自体の構文エラーとかでも起きます。 次はPHPのほうですが、レスポンス関係のログは残ってませんか?
ofuru.no.good

2018/12/13 06:57

PHPのエラー: 2018-12-13 15:56:48 Error: です。
m.ts10806

2018/12/13 07:02

んー何も返していない?ということは、 $this->request->is('ajax')がfalseになってる可能性がありますね。 補足のところにある「データが空」にもつながりました。 何かしら返すように変えてみてください。 下記のようにthrow new BadRequestException();とか。 https://www.marineroad.com/staff-blog/13276.html
ofuru.no.good

2018/12/13 07:27

if(!$this->request->is('ajax')) { throw new NotFoundException(__('POSTなし')); } で確認しましたが、処理実行されなかったので$this->request->is('ajax')自体は通っていることになります。
m.ts10806

2018/12/13 07:30

「されなかった」裏はどのように取られましたか?もしajaxのdataType:jsonのままだと同じエラーになりそうに思います。 (もしかしたらNotFoundExceptionのエラー内容がfailで受け取れるかもしれませんが・・)
ofuru.no.good

2018/12/13 08:06

↑削除リクエスト中 if ($this->request->is('ajax')) { throw new NotFoundException(__('POSTなし')); にしたところ console: 404 (Not Found) error.log: 2018-12-13 17:00:56 Error: [Cake\Http\Exception\NotFoundException] POSTなし です。
m.ts10806

2018/12/13 08:07

true判定にしたのは動作確認のためですね?
ofuru.no.good

2018/12/13 08:30

はい。そうです。 ブラウザ側でデベロッパーツールでネットワークタブを確認したところ、コントローラーが呼ばれていて request payload にPOSTデータがありました。
ofuru.no.good

2018/12/13 09:34

mts10806さん、 ご協力ありがとうございました。
m.ts10806

2018/12/13 09:34

解決されたようで何よりです
guest

回答2

0

url: "https://********/コントローラー名/faqLog",

Ajaxを発射する元のページと、
PHPがAjax通信を待ち受けるドメインは同じものですか?違うものですか?

https://example.com/から始まるドメイン名付きのリクエストの場合、
Ajaxがクロスドメインでの通信と判断している可能性があります。
JS:クロスドメインでAjax通信 - goma
CORSまとめ - Qiita

CORSの仕様では、次の条件に一つでも当てはまる場合は、実際のHTTPリクエスト(GETやPOST)を行う前に、preflight requestとしてOPTIONSリクエストを行うことが定められています。この場合、サーバ側ではGETやPOSTに加えてOPTIONSでも同様のCORS対応が必要になりますので、注意が必要です。

とのことで、クロスドメイン扱いですと先にOPTIONSでお伺いをたててから送信を試みる仕様になってますので、2度の通信を正常終了させる必要があります。
CORS用のヘッダーの設定を行っていない場合、お伺いを立てた時点で失敗しますので、重要なPOST通信の部分はPHPのコントローラ部分まで届いていないことになります。


対処法ですが同じドメインならば至ってシンプル。
AjaxのURLを"/コントローラー名/faqLog"に変更してみてください。

もし異なるドメインならば一度CORS用のヘッダーを付けてから再度確認してみてください。

投稿2018/12/13 04:21

miyabi-sun

総合スコア21158

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

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

ofuru.no.good

2018/12/13 05:16

回答ありがとうございます。ドメインは同じものです。
miyabi-sun

2018/12/13 05:30 編集

同じドメインでもフルドメインで書いている場合クロスドメイン認定される可能性がありますので、 本当にコントローラーまで到達しているのか一度確認してみてください。 PHPがApacheで動いているなら、アクセスログでどんなリクエストを受け付けたかを確認出来ますし、 ブラウザ側もデベロッパーツール(F12等)のネットワークタブで通信履歴を確認することができます。
ofuru.no.good

2018/12/13 08:16

確認したところ Request URL: https://*****/コントローラー名/faqLog Request Method: POST Status Code: 404 Not Found でした。
guest

0

自己解決

最終結果

JS

1$(function() { 2 $('#******').on('shown.bs.collapse',function() { 3 var id = "situmon"; 4 $.ajax({ 5 url: "/コントローラー名/faqLog", 6 type: "post", 7 dataType: "json", 8 beforeSend: function(xhr){ 9 xhr.setRequestHeader('X-CSRF-Token', $('[name="_csrfToken"]').val()); 10 }, 11 contentType: 'application/json', 12 data: JSON.stringify(id), 13 }).done(function(response) { 14 if (response.result === 'NG') { 15 alert('保存失敗'); 16 return false; 17 } 18 19 alert('保存成功'); 20 return true; 21 }).fail(function(XMLHttpRequest, textStatus, errorThrown) { 22 alert('\n通信失敗 \nXMLHttpRequest : ' + XMLHttpRequest.status + '\ntextStatus : ' + textStatus + '\nerrorThrown : ' + errorThrown.message +'\n'); 23 }); 24 });

controller

1public function faqLog() 2 { 3 $this->autoRender = false; 4 if ($this->request->is('ajax')) { 5 6 $request_body = file_get_contents('php://input'); 7 $id = json_decode($request_body); 8 $this->log(debug($id)); 9 10 if ($id == null) { 11 $this->Flash->boot_error(__('データなし')); 12         return $this->getResponse()->withType('json')->withStringBody(json_encode(['result' => 'OK'])); 13 } 14 15 return $this->getResponse()->withType('json')->withStringBody(json_encode(['result' => 'NG'])); 16 } 17 }

で取得できました。
協力ありがとうございました。

投稿2018/12/13 09:02

ofuru.no.good

総合スコア15

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

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

m.ts10806

2018/12/13 09:36

stringifyせずにkey:value形式のオブジェクト送ればもっと楽だったような?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問