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

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

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

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

4回答

3528閲覧

ajaxの戻り値にqが付くのはなぜ?

alche

総合スコア11

JavaScript

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

2クリップ

投稿2018/03/16 22:50

端末側 HTML+JavaScript+jQuery
サーバー側 PHP

jQuery ajax で質問です

端末側(JavaScript)
return $.ajax({
type: "GET"
, dataType: 'json'
}).done(function (result) {
return result;

}).fail(function (xhr, textStatus, errorThrown) { alert(xhr); return ""; });

サーバー側(PHP)
header('Content-Type: application/javascript; charset=utf-8');
echo json_encode( $_jsonArray );

JSON文字列は返っているようですが、返ってきた文字列がqで囲まれて
端末側でparseerrorとなり、status:200になります

試しにプレーンテキストで "HOGE"という文字列を返してみましたが
やはり q がくっついた状態になります

ブラウザはChrome、サーバー側としてATOMを使用しています。

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

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

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

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

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

maisumakun

2018/03/16 23:06

JSONのContent-Typeは「application/json」ですが、それに切り替えたらどうなりますでしょうか。
alche

2018/03/17 02:43

駄目でした。
defghi1977

2018/03/17 02:53

サーバーから返される”JSON”の形そのものを提示することは出来ますか?
alche

2018/03/17 03:09

オーダ番号、注文日、利益、手数料、商品名、送料 を配列にしたもの(A) (A)を配列にしたもの (B) echo json_encode( (B) );
defghi1977

2018/03/17 03:14

いやそうではなくて, 「q」がJSONにどのようにくっついているのかを知りたいのです. パースに失敗する”JSONもどき”をJSONに変換するためには, 「q」がどのように悪さをしているのかを考えなければならないからです.
alche

2018/03/17 04:47

戻り値の先頭に"q"が付いた状態です
退会済みユーザー

退会済みユーザー

2018/03/17 06:51

そういう具体性のないことを聞いているのではないです。サーバーから応答として返ってくるjson 文字列の先頭から最後までを書いてください。
退会済みユーザー

退会済みユーザー

2018/03/19 02:02

yambejp さんが言われるように JSONP だから Content-Type: application/javascript となっている? q がくっつているとは q( ... JSON 文字列 ... ) ということですか?
yambejp

2018/03/19 12:19

ぜひ戻り値の先頭にqがついた具体的な例を提示してほしいです。先頭にqがついても「かこまれている」とはいわないですよね?なにをもって囲まれているという表現になっているか、具体性がなくて回答者側の想像にまかせるにも限界があります
alche

2018/03/20 05:22

解決はしてませんが、とりあえず先頭がqだったら(先頭がqということはないので)削除するにしました。
退会済みユーザー

退会済みユーザー

2018/03/20 05:32

何故私の質問「q がくっつているとは q( ... JSON 文字列 ... ) ということですか? 」に答えられないのですか? なぜ、yambejp さんや私が言っているように、具体的に書けないのですか? もうどうでもいいのですかね? だったらここからは撤退しますけど。
alche

2018/03/20 19:06

q( ... JSON 文字列 ... ) になります。(JSON文字列にはお客様情報が含まれているので、具体例はご容赦ください)
defghi1977

2018/03/20 19:09

ああ, やっぱりそれJSONじゃなくてJSONPだよ
退会済みユーザー

退会済みユーザー

2018/03/21 03:30

JSONP でコールバック名が q ということですね。たぶん JSONP とするのは質問者さんの望むことではなく、普通に JSON をやり取りしたいのだと思いますが、そうであればサーバー側の実装をそのように変えてください。そうすれば jQuery ajax のコードはそのままで OK のはずです。
退会済みユーザー

退会済みユーザー

2018/03/21 03:33

サーバー側は今の実装のまま、即ち JSONP としたいということであれば、jQuery ajax のコードに若干の変更をすれば解決できると思います。それを回答欄に追記しておきます。
guest

回答4

0

勘違いかもしれませんがapiが基本的にjsonp形式で返してくる仕組みなのでは?
「qで囲まれている」というあいまいな表現がすべてを混乱させている原因だと思います
ふつうqで囲むとは戻り値が
q{abc:123}q
のようなことですよね

投稿2018/03/19 01:10

yambejp

総合スコア114572

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

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

0

ベストアンサー

あなたがJSONと表現していたそれは, 実際にはJSONP(JSONをscript要素を使ってクロスドメインで入手するテクニック)と呼ばれているものです.

例を示します.

まず, 次のようなコールバック関数を定義したとしましょう.

JavaScript

1window.q = function(data){ 2 console.log(data.name); 3}

ここでhttp://jsonp.comにアクセスすると次のようなスクリプトが返されるものとします.

JavaScript

1q( 2 { 3 "name": "ななしのごんべえ" 4 } 5)

これはあなたがJSONにqがくっついていると表現したものですが, 実際にはグローバル関数qにJSONを引数として渡しているのです.

そこで次のようなコードを実行しましょう.

JavaScript

1const script = document.createElement("script"); 2script.src = "http://jsonp.com"; 3document.body.appendChild(script);

すると, 次の処理フローが発生します.

  1. script要素がDOMに追加され, http://jsonp.comに対するリクエストが飛ぶ.
  2. http://jsonp.comからはJSONPが返され, その内容が実行される.
  3. その中でグローバル関数(コールバック関数)qが呼び出され, 結果としてJSONの内容を取り出すことができる.

つまりコンソールにはななしのごんべえと出力されることでしょう.

NOTE:
この仕組みはscript要素の特性(原則クロスドメインでのアクセスが可能)上, コールバック関数の名称さえ分かればどこからでも利用できます. そのため本質的にリスクを伴う(今回のように単なるJSONもどきと考えるのは論外である)点に注意して下さい.


q( ... JSON 文字列 ... ) になります。(JSON文字列にはお客様情報が含まれているので、具体例はご容赦ください)

我々が言いたかったのはこの構造のサンプルを提示してほしかったのであって, JSONそのものに興味はありません. ですから今後このようなリクエストがあった場合は, (JSONの等の)構造の中身を適宜ダミーデータに書き換えたものを質問に含めるようにして下さい.

投稿2018/03/20 19:29

defghi1977

総合スコア4756

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

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

alche

2018/03/20 20:30

ありがとうございます。 すぐには試すことができない状況ですが、後日試してみます。
退会済みユーザー

退会済みユーザー

2018/03/21 04:31

質問者さんは jQuery ajax を使っているようですので、script 要素を追加するために自力で JavaScript のコードを書いて対処するより、そこは jQuery ajax に任せた方がよさそうだと思います。
guest

0

PHP は知らないのでハズレかもしれませんが・・・

JSON文字列は返っているようですが、返ってきた文字列がqで囲まれて

セキュリティ対策で JSON 応答が "q" でラップされているということはないでしょうか?

JSON サービスの脆弱性(JSON 配列は JavaScript として有効)に起因する XSS 対策として、ASP.NET の Web サービスの JSON 応答は .NET 3.5 から "d" でラップされるようになりました。WCF も同様です。

それと同様な話ということはないでしょうか?

ASP.NET Web サービスで jQuery ajax を使う場合は、そのラップを外すコーディングを追加する必要があります。例えば "d" でラップされる場合は以下のようになります。

success: function (data) { if (data.hasOwnProperty('d')) { data = data.d; } // data の処置 }

ハズレでしたらすみません。もし、上記の話の詳しい説明に興味がありましたら以下の記事を見てください。

jQuery AJAX と Web サービス
http://surferonwww.info/BlogEngine/post/2011/06/04/jQuery-AJAX-and-Web-Service.aspx

WCF と jQuery AJAX
http://surferonwww.info/BlogEngine/post/2015/10/15/wcf-and-jquery-ajax.aspx

【2018/3/21 13:20 追記】

質問に対する 2018/03/21 12:33 の私のコメントで「サーバー側は今の実装のまま、即ち JSONP としたいということであれば、jQuery ajax のコードに若干の変更をすれば解決できると思います。それを回答欄に追記しておきます」と書きましたが、それを以下に書きます。

JSONP でコールバック名が q すなわち q( ... JSON 文字列 ... ) という応答が返ってくる場合(コールバック名は q で固定と理解)、jQuery ajax のパラメータを以下のようにします。

$.ajax({ url: xxxx, dataType: 'jsonp', jsonp: false, jsonpCallback: 'q' }).done(function (result) { ・・・以下略・・・

xxxx は要求先の URL です。

dataType: 'jsonp' とすると、jQuery.ajax を呼び出した時点で script タグを生成し DOM ツリーへ追加してくれます。(script タグを生成して DOM ツリーに追加するためのスクリプトを自力で書く必要はありません)

コールバック名を q とする、すなわち q( ... JSON 文字列 ... ) という応答が返ってくる場合は jsonp: false, jsonpCallback: 'q' と設定します。

応答が返ってくるとコールバックが呼び出され、コールバックの引数に設定された JSON 文字列が JavaScript オブジェクトにパースされ、done(function (result) { ... の result に渡されます。

投稿2018/03/17 01:07

編集2018/03/21 04:22
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

alche

2018/03/17 02:49

今の状況では"q"で囲まれてしまうので、「jQuery AJAX と Web サービス」を参考に改造してみたんですけど、error のほうに飛んできてやはり”parseerror"になってしまいます。 errorで飛んできたときの引数の1番目(今回はxhrという名前にしてます)の利用して if ( xhr.status == 200 && xhr.responseText.hasOwnProperty('q') ) ってしてみたんですけど、hasOwnPropertyでfalseになってしまいました。
alche

2018/03/17 02:50

ちなみにサーバー側はIISではなく、apacheを使用してます。
退会済みユーザー

退会済みユーザー

2018/03/17 02:58

error の方のコールバックに飛ぶということですと、q でラップされているということではなさそうですね。Fiddler などのキャプチャツールを使って、どういう応答が返ってきているか調べてみることをお勧めします。それでかなりのことが分かるのではないかと思われます。
退会済みユーザー

退会済みユーザー

2018/03/17 03:02

あと error のコールバックを function (jqXHR, textStatus, errorThrown) { ... } のようにして、textStatus, errorThrown がどうなっているかも調べてください。それにも問題解決に有用な情報が含まれていると思います。
退会済みユーザー

退会済みユーザー

2018/03/17 04:44

Fiddler が何かは以下の記事を見てください。Chrome のディベロッペパーツール、IE の F12 開発者ツールでもキャプチャできますが、Fiddler が使いやすいので自分的にはお勧めです。IE, Firefox, Chrome いずれにも使えます。 Fiddler のお勧め http://surferonwww.info/BlogEngine/post/2011/05/25/Recommendation-of-Fiddler.aspx 上の記事の画像(クリックすると拡大画像が表示されます)の右下のウィンドウで TextView にすると、応答とした返ってきた JSON 文字列がどうなっているかが分かります。
guest

0

以下の部分ですが…

JavaScript

1}).done(function (result) { 2return result; 3 4})

ajaxは非同期処理なので、return result; としても戻り値を受け取れません。ここに処理の中身を書けば正常に値を受け取れると思います。

投稿2018/03/16 23:56

ockeghem

総合スコア11701

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

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

alche

2018/03/17 02:51

同期にするために async: false を設定してます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問