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

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

ただいまの
回答率

88.92%

xmlhttpで取得した複数の項目を任意の場所に別々に表示したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 150

tajix_japan

score 90

javascriptでゲームを作っています。

ゲームのデータそのものはサーバーに保管し、クライアント側では、サーバー上の文字を表示するだけの仕様となります。

データそのものは下記のサーバーに保管されています。

https://example.com/data.php

ユーザーID(sha256)とパスワード(新規接続ごとに毎回発行したものをcookieで保管)をPOSTすることにより、下記の表示が可能です。
<div id="point">256</div>
<div id="money">45000</div>

現在の仕様

xmlhttpで取得したものをクライアント側で表示させます。

ただ
https://example.com/data.php
を xmlhttpで取得すると

<div id="point">256</div>
<div id="money">45000</div>

がまとまって表示されてしまいます。

ポイント、保有金額は任意の場所に分けて表示させたいため、
data_point.php とdata_money.phpを新たに作り、それぞれはポイントと
金額だけを表示するようにします。

https://example.com/data_point.php
<div id="point">256</div>

https://example.com/data_money.php
<div id="money">45000</div>

上記のように2つのPHPに分けて独自に表示させ、
そこから取得できた
<div id="my_money_view_p"></div>

<div id="my_point_view_p"></div>

を任意の場所に置くことにより、ポイントと金額を別々の場所に表示させています。

  <script language="javascript" type="text/javascript">
  function OnButtonClick() {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function () {
      var READYSTATE_COMPLETED = 4;
      var HTTP_STATUS_OK = 200;
      if (this.readyState == READYSTATE_COMPLETED && this.status == HTTP_STATUS_OK) {
        // レスポンスの表示
        var outFrame = document.getElementById('my_money_view_p');
        outFrame.innerHTML = this.responseText;
      }
    }
    var textBox1 = document.getElementById('Text1');
    var textBox2 = document.getElementById('Text2');
    var PostData = encodeURIComponent('usr') + '=' + encodeURIComponent(textBox1.value)
      + '&' + encodeURIComponent('pass') + '=' + encodeURIComponent(textBox2.value);
    PostData = PostData.replace(/%20/g, '+');
    xmlhttp.open('POST', 'https://example.com/data_money.php');
    xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlhttp.send(PostData);
  }
  </script>
</head>
<body>
  <input id="Text1" type="hidden" name="usr"/><br/>
  <input id="Text2" type="hidden" name="pass"/><br/>

<script>
  $("[name='usr']").val(usr);
  $("[name='pass']").val(pass);
</script>
  <input id="my_money_click_p" type="hidden" value="送信" onclick="OnButtonClick();"/>
  <div id="my_money_view_p"></div>
</body>
</html>
<script>
document.getElementById('my_money_click_p').click();
</script>




  <script language="javascript" type="text/javascript">
  function OnButtonClick() {
    var xmlhttp44 = new XMLHttpRequest();
    xmlhttp44.onreadystatechange = function () {
      var READYSTATE_COMPLETED = 4;
      var HTTP_STATUS_OK = 200;
      if (this.readyState == READYSTATE_COMPLETED && this.status == HTTP_STATUS_OK) {
        // レスポンスの表示
        var outFrame44 = document.getElementById('my_point_view_p');
        outFrame44.innerHTML = this.responseText;
      }
    }
    var textBox144 = document.getElementById('Text144');
    var textBox244 = document.getElementById('Text244');
    var PostData = encodeURIComponent('usr') + '=' + encodeURIComponent(textBox1.value)
      + '&' + encodeURIComponent('pass') + '=' + encodeURIComponent(textBox2.value);
    PostData44 = PostData44.replace(/%20/g, '+');
    xmlhttp44.open('POST', 'https://example.com/data_point.php');
    xmlhttp44.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlhttp44.send(PostData44);
  }
  </script>
</head>
<body>
  <input id="Text144" type="hidden" name="usr"/><br/>
  <input id="Text244" type="hidden" name="pass"/><br/>

<script>
  $("[name='usr']").val(usr);
  $("[name='pass']").val(pass);
</script>
  <input id="my_point_click_p" type="hidden" value="送信" onclick="OnButtonClick();"/>
  <div id="my_point_view_p"></div>
</body>
</html>
<script>
document.getElementById('my_point_click_p').click();
</script>

やりたいこと。

現在は
金額については
xmlhttp.open('POST', 'https://example.com/data_money.php');で <div id="my_money_view_p"></div>を取得、

ポイントについては
xmlhttp44.open('POST', 'https://example.com/data_point.php');で<div id="my_point_view_p"></div>を取得していますが、

このように、phpが項目ごとに独立しているのではなく、

xmlhttp.open('POST', 'https://example.com/data.php');の1回だけで
<div id="point">256</div>
<div id="money">45000</div>
を一気に取得し、
<div id="my_point_view_p"></div>
および
<div id="my_money_view_p"></div>
をそれぞれ任意の場所に表示できるようにしたいというのが希望です。

PHPを用いたスクレイピングでは、1回に複数のIDを取得し、それぞれを
任意の場所に表示させることが可能ですが、同じようなことを希望しています。

このようなことが可能かご教示いただきたくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

https://example.com/data.php
を xmlhttpで取得すると
<div id="point">256</div>
<div id="money">45000</div>
がまとまって表示されてしまいます。

まとまって表示されるのは、innerHTML に代入して表示の命令をしているからです。

普通は、表示前にデータをJavaScriptで扱いやすい形に変換します。
応答結果が(XMLなどの)マークアップ言語である場合、DOMParserを使います。

var responseText = `<div id="point">256</div>
<div id="money">45000</div>`;

var parser = new DOMParser();
var parsed = parser.parseFromString( responseText, "text/html");
console.log( parsed ); // html > body に 格納される。
var data = {
  point: parsed.getElementById("point").textContent|0,
  money: parsed.getElementById("money").textContent|0
}
console.log( data ); // {point:256,money:45000}

https://example.com/data.php に POSTすると、上記のように2種類の値を取得できるので、必要な値 data.money または data.point それぞれを個別にDOM操作で書き換えできます。

したがって、以下のエンドポイント実装は無駄です。

  • https://example.com/data_money.php
  • https://example.com/data_point.php

また、応答を JSON とすることで JSON.parse() が使えますので値を活用しやすくなります。

  • https://example.com/data.php に POST
    => {point:256,money:45000} を応答となるサーバー実装にする。

xmlhttp ではなく、xhr(XMLHttpRequest)と略記するのが一般的です。
また、XHRを使うのであれば、ユーザ関数を作ってコールバック関数を与える方式にし、エンドポイント、応答後の処理関数だけを与える形にします。
コードを読む限り、jQuery.ajax() を使うのが良いと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/24 15:36

    有難うございます。
    まさに、探していた機能です。
    ありがとございます。
    早速、使用してみました。

    下記で、
    text = "<div><money>150,000</money><point>38</point></div>";
    に記載されているmoneyとpointを分けて表示することが可能でした。


    <BR>+++++++++demo+++++++++++++<BR>
    <p id="demo"></p>
    <BR>+++++++++demo2+++++++++++++<BR>
    <p id="demo2"></p>
    <BR>+++++++++++++++++++++++++++<BR>
    <script>
    text = "<div><money>150,000</money><point>38</point></div>";

    var text, parser, xmlDoc;
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(text,"text/xml");
    document.getElementById("demo").innerHTML =
    xmlDoc.getElementsByTagName("point")[0].childNodes[0].nodeValue;

    var text, parser2, xmlDoc2;
    parser = new DOMParser();
    xmlDoc2 = parser.parseFromString(text,"text/xml");
    document.getElementById("demo2").innerHTML =
    xmlDoc2.getElementsByTagName("money")[0].childNodes[0].nodeValue;

    </script>




    次に、
    text = "<div><money>150,000</money><point>38</point></div>";
    の部分を直書きではなく、PHPから拾ってきます。


    まず、サーバー側のPHPを下記に書き換えました。

    <?php header("Access-Control-Allow-Origin: *"); ?>
    <div><money>120,300</money><point>638</point></div>

    次に、javascriptの内容を下記としました。
    前回作ったjavascriptの内容を今回作ったjavascriptと合体させたつもりなのですが
    PHPの内容を表示することができませんでした。

    やってみたことは、

    text = "<div><money>150,000</money><point>38</point></div>";

    の部分を
    text = ""+ data + "";

    と変えてみました。
    document.getElementById("test_view").innerHTML = data;
    のdataをtext に渡したつもりです。
    しかしphpの内容を今回作ったjavascriptに渡すことができません。

    text = ""+ data + ""; 
    の部分はどう記載すればいいかご教示いただけませんでしょうか?

    よろしくお願いいたします。



    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script type="text/javascript">
    var xmlHttp;
    function loadText(){
    xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = checkStatus;
    xmlHttp.open("GET", "http://example.com/test.php", true);
    xmlHttp.send(null);
    }
    function checkStatus(){
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
    // alert(xmlHttp.responseText);
    // alert(xmlHttp.responseText);
    var data = xmlHttp.responseText; // E
    document.getElementById("test_view").innerHTML = data;
    // 読み込み終わったら画像を消す
    //document.getElementById("loading").innerHTML = '';
    }
    }
    </script>
    </head>
    <body>
    <form>
    <input id="test_click" type="hidden" onClick="loadText()">
    </form>
    <script>
    document.getElementById('test_click').click();
    </script>
    <div id="test_view"></div>


    <BR>+++++++++demo+++++++++++++<BR>

    <p id="demo"></p>


    <BR>+++++++++demo2+++++++++++++<BR>

    <p id="demo2"></p>

    <BR>+++++++++++++++++++++++++++<BR>

    <script>
    text = ""+ data + "";
    var text, parser, xmlDoc;
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(text,"text/xml");
    document.getElementById("demo").innerHTML =
    xmlDoc.getElementsByTagName("point")[0].childNodes[0].nodeValue;


    var text, parser2, xmlDoc2;
    parser = new DOMParser();
    xmlDoc2 = parser.parseFromString(text,"text/xml");
    document.getElementById("demo2").innerHTML =
    xmlDoc2.getElementsByTagName("money")[0].childNodes[0].nodeValue;

    </script>

    キャンセル

  • 2020/07/24 15:57 編集

    xhrのイベントリスナの中で、PHPからの応答を利用できるようになります。
    DOMParserは、イベントリスナ内で実行してください。
    追記)GET async に仕様変更していますね。
    表示されないのは var data のスコープによるものと思います。

    キャンセル

  • 2020/07/24 16:29

    有難うございます。
    下記で無事取得できました。
    大変助かりました。
    深く御礼申し上げます。

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script type="text/javascript">
    var xmlHttp;
    function loadText(){
    xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = checkStatus;
    xmlHttp.open("GET", "http://example.com/test.php", true);
    xmlHttp.send(null);
    }
    function checkStatus(){
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
    var data = xmlHttp.responseText; // E

    var data, parser, xmlDoc;
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(data,"text/xml");
    document.getElementById("demo").innerHTML =
    xmlDoc.getElementsByTagName("point")[0].childNodes[0].nodeValue;

    var data, parser2, xmlDoc2;
    parser = new DOMParser();
    xmlDoc2 = parser.parseFromString(data,"text/xml");
    document.getElementById("demo2").innerHTML =
    xmlDoc2.getElementsByTagName("money")[0].childNodes[0].nodeValue;

    }
    }
    </script>

    <form>
    <input id="demo_click" type="hidden" onClick="loadText()">
    </form>
    <script>
    document.getElementById('demo_click').click();
    </script>




    <BR>+++++++++demo+++++++++++++<BR>

    <p id="demo"></p>

    <BR>+++++++++demo2+++++++++++++<BR>

    <p id="demo2"></p>

    <BR>++++++++++++++++++++++++++++<BR>

    キャンセル

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

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

関連した質問

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