🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JSON

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

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

4回答

6724閲覧

Laravel 6.2 response()->json();でContent-Type textが返る

larachan

総合スコア28

JSON

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

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

3クリップ

投稿2019/12/25 08:35

編集2019/12/25 09:31

前提・実現したいこと

APIでJsonレスポンスを返すように作成したのですが、
公式のドキュメントを見たところ、下記の通りでした。

readoubleに書いてあったこと

return response()->json([ 'name' => 'Abigail', 'state' => 'CA' ]);

追記-実行環境です

$ php -v PHP 7.2.23 (cli) (built: Sep 25 2019 07:38:48) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies $ rpm -qa | grep php php72-runtime-2.0-1.el7.remi.x86_64 php72-php-7.2.23-1.el7.remi.x86_64 php-cli-7.2.23-1.el7.remi.x86_64 php-gd-7.2.23-1.el7.remi.x86_64 php72-php-json-7.2.23-1.el7.remi.x86_64 php72-php-cli-7.2.23-1.el7.remi.x86_64 php72-2.0-1.el7.remi.x86_64 php-json-7.2.23-1.el7.remi.x86_64 php-7.2.23-1.el7.remi.x86_64 php-mbstring-7.2.23-1.el7.remi.x86_64 php-xml-7.2.23-1.el7.remi.x86_64 php-pdo-7.2.23-1.el7.remi.x86_64 php-pecl-zip-1.15.5-1.el7.remi.7.2.x86_64 php72-php-common-7.2.23-1.el7.remi.x86_64 php-common-7.2.23-1.el7.remi.x86_64 php-devel-7.2.23-1.el7.remi.x86_64 php-pecl-mcrypt-1.0.3-1.el7.remi.7.2.x86_64

POSTMANで確認したところ、Content-Type textで返却されました。

試したこと

$json = json_encode($response);
header('Content-Type: application/json');
echo $json;

上記だとJson形式で返却されました。

response()->json();
は上手く動いていないのでしょうか?

API開発をされている方どのようにされているか教えていただけると幸いです。

宜しくお願い致します。

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

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

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

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

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

guest

回答4

0

私はいつもこの書き方でContent-Type: application/jsonになります。
普段は、REST Clientで確認していますが、先ほどPOSTMANやcURLで確認しても、jsonになりました。

PHP

1 $data_json = [ 2 'name' => 'Abigail', 3 'state' => 'CA' 4 ]; 5 6 return response()->json( 7 $data_json, 8 200, 9 [], 10 JSON_UNESCAPED_UNICODE 11 );

バージョンはこんな感じです。Laravel5系でも動いていました。

PHP: 7.3.6 Laravel: 6.0.4 Composer: 1.9.0

投稿2019/12/25 09:50

kota_yamashita

総合スコア356

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

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

larachan

2019/12/25 10:43

お忙しいところ、試して頂きありがとうございます。 頂いた以下のソースで試してみました。 return response()->json( [ 'name' => 'Abigail', 'state' => 'CA' ], 200, [], JSON_UNESCAPED_UNICODE ); がJson形式では返却されなかったです。 phpのバージョン関係あるのですかね? 一旦バージョン上げてみて再度確認してみます。
guest

0

ベストアンサー

Symfony HTTP Foundation の JsonResponse のソースを読んでみると以下のようになっております。

php

1 /** 2 * Updates the content and headers according to the JSON data and callback. 3 * 4 * @return $this 5 */ 6 protected function update() 7 { 8 if (null !== $this->callback) { 9 // Not using application/javascript for compatibility reasons with older browsers. 10 $this->headers->set('Content-Type', 'text/javascript'); 11 12 return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data)); 13 } 14 15 // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback) 16 // in order to not overwrite a custom definition. 17 if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) { 18 $this->headers->set('Content-Type', 'application/json'); 19 } 20 21 return $this->setContent($this->data); 22 }

明示的に Content-Type ヘッダがセットされていなければ

php

1$this->headers->set('Content-Type', 'application/json');

が自動的に呼ばれるはずですが,ミドルウェアで何か細工をしていたりしませんかね? header 関数だと正常に動き,フレームワークの機構に乗ると失敗するということは Laravel レイヤでのミドルウェア が非常に怪しいです。 Nginx 等の Web サーバは逆に問題ないと思います。

またミドルウェアは直接自分で登録しなくても, サービスプロバイダからの登録も可能 なので,品質の悪いパッケージをインストールしていると自動実行されるそれのサービスプロバイダが問題を引き起こしている可能性もあります。

投稿2020/01/09 09:24

mpyw

総合スコア5223

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

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

larachan

2020/01/09 10:03

Kernel.phpにおいて、 protected $middlewareGroups = [ ・・・ 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\RequireJson::class, ], ]; こちらのMidlewareのみが呼ばれる認識でしたが、、、 protected $middleware = [ 内に過去にbladeを作成していた際にXSS対策として $response->header('Content-Type', 'charset=UTF-8'); を付随する処理を記載してました。 削除したところ問題なくJsonレスポンスが返却されました! APIではprotected $middleware = [ はルーティングで指定しないと呼ばれない認識でしたが、そうじゃあないんですね。。 この問題を解決して頂きありがとうございました!
larachan

2020/01/09 10:05

回答頂いた方皆さんありがとうございました!
guest

0

何らかの問題があってコントローラーが値を返すところまで処理が到達していないパターンではないでしょうか。

何らかの問題とは例えば

  • ルート定義にないリクエストを送っている(パスを間違えたとかメソッドが違うとか)
  • 認証ミドルウェアを使っていて認証に失敗している

などです。

このとき、response()->json(...)でjsonを返そうとしているとLaravelが知る由はなく、返却内容はリクエストのAcceptヘッダで決まります。Acceptヘッダがなければデフォルトのtext/htmlになります。

レスポンスのボディでエラー表示が返っているはずなので、中身を見るといいかもしれません。

投稿2019/12/27 22:04

crhg

総合スコア1177

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

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

larachan

2020/01/06 05:26

遅くなりました。 ルーティングに関してはRoute::resourceを使用し、HTTPメソッドはGETで試しております。 認証のMidlewareは呼び出していません。 Acceptヘッダがなかったので、Midlewareを作成し、 $request->headers->set('Accept','application/json'); 上記の形で付与してみましたが、上手く行きませんでした。。。 レスポンスボディはエラーは特に無いので、行き詰まっております。。
crhg

2020/01/06 06:09

ここでいう「リクエストのAcceptヘッダ」はLaravelの側の話ではなく、クライアントから送られてくるもののことを言っています。POSTMANならHeadersタブで設定できます。 レスポンスにエラーはないということですが、具体的にはどんな物が返っているのでしょう。
larachan

2020/01/06 08:11

POSTMANのヘッダーは設定済みでした。 CODEを確認すると下記のリクエストを投げています。 GET /api/パス HTTP/1.1 Host: ipアドレス Content-Type: application/json レスポンスボディは以下です。 {"name":"Abigail","state":"CA"} レスポンスヘッダーは以下になります。 Server:Apache X-Powered-By:PHP/7.2.26 Cache-Control:no-cache, private X-RateLimit-Limit:60 X-RateLimit-Remaining:59 X-Frame-Options:DENY Content-Length:31 Keep-Alive:timeout=5, max=99 Connection:Keep-Alive Content-Type:charset=UTF-8 以上、宜しくお願い致します。
crhg

2020/01/09 04:35

レスポンスのボディにコントローラで設定するはずの値が入っているので処理はコントローラまでは来てそうです。LaravelはContent-typeヘッダについては基本的にフレームワークが面倒を見てくれるので何もしなければちゃんと設定されるはずなのですが。content-typeがcharset岳になっているのもかなりおかしいです。これ以上は他の部分のプログラムも示されないと追いかけるのは難しいです。
larachan

2020/01/09 06:22

レスポンスヘッダーのContent-Type UTF-8は自分もおかしいと思いました。 再現性がないので、しばらくechoで対応します。。
guest

0

PHPの基本仕様ですね、それ

PHP

1header('Content-Type: application/json');

MIME情報を付与しないと、PHPファイルはtext/html形式としか認識しないので、JSONをうまく処理できません。これはAjax処理するときに、初心者が皆陥る罠としても知られています。また、そのヘッダを付与するときは必ずUTF-8に指定しておいた方がいいですよ。JSONはUTF-8以外の動作を保障してませんので。

JSON リクエストとレスポンス

投稿2020/01/09 01:41

編集2020/01/09 01:44
FKM

総合スコア3647

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

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

mpyw

2020/01/09 03:34

Laravel およびベースとなっている Symfony フレームワークがその部分を隠蔽して実行してくれるはずが、どういうわけか動いていないようだ、という趣旨の質問だと思います。
larachan

2020/01/09 06:19 編集

mpywさん おっしゃる通りです。 今はechoで対応してますが。。。
mpyw

2020/01/09 09:03

いやむしろ閉じると正しく動かないですね… exit するとそこから後の処理は register_shutdown_function 関数で登録された処理しか動かなくなりますね。PSR-7 と似た形式のレスポンスオブジェクトが response()->json() の呼び出しによって作られ,カーネルがレスポンスを送信する直前にヘッダー送信およびレスポンスの文字列化処理が行われるはずです。
FKM

2020/01/09 09:28 編集

だとすると、これと同じ現象でしょうか?これも同じAPIで試しているようです。 https://stackoverflow.com/questions/42837126/laravel-return-text-html-and-not-json その中で有効そうな回答(8人の評価)があり、 Laravel provides modify header information using Response class. 訳すると、LaravelはResponseクラスを使用することでヘッダ情報の変更を適用できます。 Try this way in your controller : コントローラ設定をこの方法で試してみてください。とあります。 $contents = View::make('embedded')->with('foo', $foo); $response = Response::make($contents, $statusCode); $response->header('Content-Type', 'text/plain'); return $response; Responseクラスを使用していないか、あるいは適用されていない、そもそもの設定がされていない可能性も考えられます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問