LoginSignup
9
8

More than 5 years have passed since last update.

【Vue.js】axios XML値を取得できた時の方法【Ajax】

Last updated at Posted at 2018-10-31

Vus.js + axios でJSON取得の記事は多数あるのですが、

XML取得の記事をなかなか見つけられず苦戦したのでアップしておきます。

後ほどブログも書きます。

teratailでもご相談させていただきました。(ありがとうございます。)

(Vue.js axios XML取得しようとすると HTMLCollectionが空 TypeError: 'caller', 'callee', and 'arguments' properties

index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <title>テスト</title>
</head>

<body>
  <div id="app">

  </div>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script src="https://unpkg.com/vue"></script>
  <script src=".config.js"></script>
  <script src="app.js"></script>
</body>

</html>

app.js
// script.js
"use strict";

const JalanBaseUrl = 'http://jws.jalan.net/APICommon/AreaSearch/V1/?key=';
const ApiKey = config.KEY;

const vm = new Vue({
  el: '#app',
  data: {
  },
  methods: {
    get_location: function () {
      const request = 'ajax.php?url=' + JalanBaseUrl + ApiKey

      axios.get(request, {
        timeout: 3000,
        responseType: 'document'
      })
        .then(function (response) {
          const xml = response.data;

         const areas = xml.getElementsByTagName('prefecture');

         //グーグルクロムのコンソールで確認用
         //console.log(areas)

          // 返り値がHTMLCollection型という確認
          //console.log(Object.prototype.toString.call(areas));

          for (var i = 0; i < areas.length; i++) {

            const largeareas = areas[i].getElementsByTagName('largearea');

            for (var j = 0; j < largeareas.length; j++) {

              const objPrefs = {
                //HTMLCollectionはattributesで指定必要あり
                pref_code: areas[i].attributes[0].value,
                pref_name: areas[i].attributes[1].value,
                large_code: largeareas[j].attributes[0].value,
                large_name: largeareas[j].attributes[1].value
              };

              vm.$data.prefs.push(objPrefs);
            }
          }
        })
        .catch(function (error) {
          console.log(error);
        });

    }

  },

  created: function (pref_large_code) {
    this.get_location();
  }

});

ajax.php
<?php
  if(isset($_GET["url"]) && preg_match("/^https?:/",$_GET["url"])){
    $data = file_get_contents($_GET["url"]);
    $data = mb_convert_encoding($data, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
    header("Access-Control-Allow-Origin: *");
    echo $data;

  }else{
    echo "error";
  }

.config.js
const config = {
  KEY: "API_KEY"
}

コメントも記載していますが、

XMLにはidやclassがない事が多いので、

getElementsByTagName('タグ名');

でタグを指定して取得しています。

HTMLCollection型で返ってくるため、attributesを指定すれば取得できます。

pref_code: areas[i].attributes[0].value

attributesはconsole.logで出力しつつ、グーグルクロムのコンソール画面で確認しました。
(もっといい方法があるかも?)

XMLが取得できるURLとできないURLがあった・・

上記でXML値取得できたのですが、一部のURLでは値が取得できず。。。

ずっとググって、下記の記事で対応できました。

Axios(vue.jsのajax)で外部APIをたたく時のクロスドメイン問題を(サクッと)解決したメモ

ajax2.php
<?php
$url = 'http://jws.jalan.net/APILite/HotelSearch/V1/?key=API_KEY&pref=010000';
$xml= file_get_contents($url);
header("Access-Control-Allow-Origin: *");
print $xml;

XML取得できるURLとできないURLの違いは URLクエリありなしかも?

と思いつつ結局まだはっきりしていませんが、

クロスドメイン対策しっかりすればXMLでも値取得できるようです。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8