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

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

ただいまの
回答率

90.86%

  • JavaScript

    14234questions

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

【javascript】status200を拾ってからレスポンス成功時の処理

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 805

tajix_japan

score 61

下記のようなAPIがあります。
このAPIはindex.htmlからもらったデータをsearch1.phpに投げ、JSON方式のコールバックを拾ってくるAPIです。
ただsearch1.phpはレスポンスが鈍く2秒ほど掛かるため、下記のapiのままでは、states200を返す前にデータを送ってしまい毎回nullを返してきます。
このapi.jsについて、「search1.phpがstatus200を返してからレスポンス成功時の処理をさせたい」というのが趣旨です。

if (send_data.readyState == 4 && send_data.status == 200){ }

という処置を嚙ませればいいのはおよそ見当がつくのですが、どう記載すればいいかがわかりません。(適当においた場所では上手くいきませんでした)
お手数ですが、下記のソースを修正いただけますでしょうか?
よろしくお願いいたします。

api.js

$(function() {
  //  クリックイベントにajax処理を登録する
  $('body').on('click', 'button[data-btn-type=ajax]', function(e) {
    console.log('click btn');
    //  リクエストの下準備
    //  リクエスト時に一緒に送るデータの作成
    var send_data;
    send_data = {
      //  テキストボックスの値を設定
      user_type : $('input').val()
    };
    console.log(send_data);
    //  WebAPIを叩く
    $.ajax({
      //  リクエストの内容
      url: 'search1.php',
      dataType: "json",
      data: send_data,
      //  レスポンス成功時の処理
      success: function(responce) {
        if (responce.result === "OK") {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        } else {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        }
        return false;
      },
      //  レスポンス失敗時の処理
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        console.log(XMLHttpRequest);
        console.log(textStatus);
        console.log(errorThrown);
        $('div[data-result=""]').html(JSON.stringify("データ取得中にエラーが発生しました。"));
        return false;
      }
    });
    //  フォーカスをテキストボックスに合わせる
    $('input').focus();

    return false;
  });
});

尚、自分なりに置いてみてうまくいかなかったのは下記です。

//  リクエストの内容
url: 'search1.php',
dataType: "json",
data: send_data,


success: function(responce) 

の間にif (send_data.readyState == 4 && send_data.status == 200)を置くしかないと思うのですが。

そうするとカンマ区切りの中に無理やりIF文を入れることになるため動かないだろうと思いながらやったのですがやはり動きませんでした。

$(function() {
  //  クリックイベントにajax処理を登録する
  $('body').on('click', 'button[data-btn-type=ajax]', function(e) {
    console.log('click btn');
    //  リクエストの下準備
    //  リクエスト時に一緒に送るデータの作成
    var send_data;
    send_data = {
      //  テキストボックスの値を設定
      user_type : $('input').val()
    };
    console.log(send_data);
    //  WebAPIを叩く
    $.ajax({
      //  リクエストの内容
      url: 'search1.php',
      dataType: "json",
      data: send_data,
      //  レスポンス成功時の処理

//追加してみた

if (send_data.readyState == 4 && send_data.status == 200){

      success: function(responce) {
        if (responce.result === "OK") {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        } else {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        }
        return false;
      },
      //  レスポンス失敗時の処理
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        console.log(XMLHttpRequest);
        console.log(textStatus);
        console.log(errorThrown);
        $('div[data-result=""]').html(JSON.stringify("データ取得中にエラーが発生しました。"));
        return false;
      }
    });
    //  フォーカスをテキストボックスに合わせる
    $('input').focus();

    return false;
  });
});

//追加してみた
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • guest1213

    2017/01/07 16:16

    「レスポンス成功時の処理をさせたい」これを行っているのがあなたが最初のソースで「// レスポンス成功時の処理」と書いている部分です。目的は達成されているはずです。期待した結果が得られないのは他に問題があるのではないでしょうか?

    キャンセル

  • tajix_japan

    2017/01/07 22:44

    有難うございます。jQueryのajax内ですでにこの判定は行われいますという指摘を受けていますのでソースの改造というよりも何が原因かを突き止めないといけないということですね。有難うございました。

    キャンセル

  • guest1213

    2017/01/07 22:56

    他の方の回答とコメントを拝見したところChunked Encodingでレスポンスがあるのですね。私は再現や自分の回答を確認できる環境が無いので回答は控えますが、"chunked encoding ajax"などで検索すると実装例や解説なども見つかるかもしれませんね。

    キャンセル

  • tajix_japan

    2017/01/08 06:52

    有難うございます。turbgraphics200さんから$.ajaxでは、readyStateが4しか処理しないため、普通のやり方だとChunked Encodingを処理することができません。 ということをご教示戴きました。無事他の方法で解決できました。お手数をおかけいたしました。有難うございました。

    キャンセル

回答 3

+4

そのsearch1.phpはHTTP Chunked Encodingでレスポンスを返しているのでしょうか。
Chunked Encodingかどうかの確認は、Chromeで開発ツール(devTools)を開いて、Networkタブを表示させておき、再度、bodyをクリックしてリクエストを投げてみて、search1.phpのResponse Headersに"Transfer-Encoding: chunked"という項目があれば、HTTP Chunked Encodingとなります。

それと、send_data.readyState == 4 && send_data.status == 200を追加とかいう話をしていますが、
jQueryのajax内ですでにこの判定は行われいます(行わないとまず無理)。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/07 22:40

    有難うございます。レスポンスヘッダーは下記の通りです。HTTP Chunked Encodingになっているようです。

    >jQueryのajax内ですでにこの判定は行われいます(行わないとまず無理)。

    やはりそうでしたか。小さいhtmlファイルは読めるので接続そのものに問題はなさそうです。
    レスポンスの遅いサーバーになった途端読めなくなるので困っています。

    Connection:Keep-Alive
    Content-Type:text/html; charset=utf-8
    Date:Sat, 07 Jan 2017 13:19:03 GMT
    Keep-Alive:timeout=15, max=500
    Server:Apache/2.2.15 (CentOS)
    Transfer-Encoding:chunked

    キャンセル

checkベストアンサー

+3

やはり、そうでしたか。
Chunked Encodingは、レスポンスをストリーミングで返します。
つまり、データをある程度のサイズで分割してレスポンスを返します。
Chunked Encodingの場合、途中のデータのレスポンスではreadyStateが3となります。(たしか)
$.ajaxでは、readyStateが4しか処理しないため、普通のやり方だとChunked Encodingを処理することができません。
このブログに書かれているようにxhrFieldsを使って、チャンクデータを取得することができます。
$.ajaxをどうしても使用しなければならないということじゃなければ、普通にxhrを使用して実装したほうがいいかと。
xhrでの実装例

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/08 06:39

    有難うございます。
    >$.ajaxでは、readyStateが4しか処理しないため、普通のやり方だとChunked Encodingを処理することができません。
    そうだったんですね。疑問が解けました。何回やっても出来ないわけですね。本当にありがとうございます。
    自分なりにググって、下記の方法であれば今回の当方のページを取得出来ました。
    これで次に進めそうです。深く感謝いたします。有難うございました。
    http://www.ajaxtower.jp/ini/http/index4.html

    キャンセル

+2

$.ajax()は非同期通信で、レスポンスが返ってくる前に次の処理に行ってしまうので、それを解決したいという質問だと読みました。
asyncをfalseに設定して、同期通信にしてしまうというのはどうでしょうか?

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>タイトル</title>
</head>
<body>
<form>
    <label>名前:
        <input type="text" name="name">
    </label>
    <input type="button" id="button1" value="submit">
</form>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
    $("#button1").on("click", function () {
        var formData = $('form').serialize();
        $.ajax({
            type: "POST",
            url: "test.php",
            async: false,
            data: formData,
            success: function (response) {
                alert(response);
            }
        });
    });
</script>
</body>
</html>
<?php
if (!empty($_POST)) {
    $name = $_POST["name"];
    echo "$name";
}

追記

alwaysを使う方法を追記します。こちらを使うほうが良いです。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>タイトル</title>
</head>
<body>
<form>
    <label>名前:
        <input type="text" name="name">
    </label>
    <input type="button" id="button1" value="submit">
</form>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
    $("#button1").on("click", function () {
        var formData = $("form").serialize();
        $.ajax({
            url: "test.php",
            type: "POST",
            data: formData
        }).always(function (data, statusText, jqXHR) {
            switch (jqXHR.status) {
                case 200:
                    alert("通信成功");
                    alert(data);
                    break;
                case 404:
                    alert("404");
                    break;
                default:
                    alert("不明なエラー");
            }
        });
    });
</script>
</body>
</html>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/07 15:29

    有難うございます。
    当方のソースにasync: false,をdata: send_data,の直後に入れてみました。
    単純なHTMLであれば問題なく表示されましたが、今回のサーバー情報は表示することができませんでした。残念です。有難うございました。

    キャンセル

  • 2017/01/07 16:13

    > レスポンスが鈍く2秒ほど掛かる
    async: falseにするとこの2秒の間はブラウザがフリーズします。同期通信は絶対にしてはいけないと思います。

    キャンセル

  • 2017/01/07 16:58

    async:falseは非推奨のようですね。失礼しました。

    キャンセル

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

  • ただいまの回答率 90.86%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    14234questions

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