如何从单独的域请求JSON数据并自己使用

时间:2019-07-02 19:07:04

标签: javascript php html json

  1. 我正在尝试使用来自“ https://www.purpleair.com/json?show=13165”的JSON数据,并将数据放在我的网站上。
  2. 我正在尝试访问JSON字段名称“ Stats”,并且试图获取子字段名称“ \” v \”'。这是Purpleair提供的文档。 https://docs.google.com/document/d/15ijz94dXJ-YAZLi9iZ_RaBwrZ4KtYeCy08goGBwnbCU/edit(第二页)

我使用XMLHttpRequest()编写了代码。它在W3Schools上说您不能跨域访问,当我尝试使用PHP遵循他们的指示时,我迷路了。我不拥有Purpleair.com

<!DOCTYPE html>
<html>
<head>
    <title>Your Page Title</title>
</head>

<body>
    <h1>Hello</h1>
    <p id='demo'></p>
    <script src="jsonp.php">
        function reqListener() {
            var myObj = JSON.parse(this.responseText);
            document.getElementById("demo").innerHTML = myObj.stats
        }
        function loadData() {
            var oReq = new XMLHttpRequest();
            oReq.addEventListener("load", reqListener);
            oReq.open("GET", "https://www.purpleair.com/json?show=13165");
            oReq.send();
        }
        loadData()
    </script>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

您可以像这样从PurpelAir获取JSON:

function reqListener() {
  // parse the the data
  var data = JSON.parse(this.responseText)
  // create an array from the required data (result.Stats -> watch the capital 'S')
  var mappedData = data.results.map(item => item.Stats)
  // display data
  document.getElementById('demo').innerHTML = mappedData.join()
}

function loadData() {
  var oReq = new XMLHttpRequest();
  oReq.addEventListener("load", reqListener);
  oReq.open("GET", "https://www.purpleair.com/json?show=13165");
  oReq.send();
}

loadData()
<h1>Hello</h1>
<p id="demo"></p>

有关XMLHttpRequest的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

我在下面重新编写了您的代码:

<!DOCTYPE html>
<html>

<head>
  <title>Your Page Title</title>
</head>

<body>
  <h1>Hello</h1>
  <!-- make ' to " in the ID-->
  <p id="demo"></p>
  <!-- no src for the script -->
  <script>
    function reqListener() {
      var myObj = JSON.parse(this.responseText);
      // this myObj.stats doesn't exist (try console.log(myObj))
      document.getElementById("demo").innerHTML = myObj.stats
      // instead try this:
      document.getElementById("demo").innerHTML = myObj.results.map(item => item.Stats).join()
    }

    function loadData() {
      var oReq = new XMLHttpRequest();
      oReq.addEventListener("load", reqListener);
      oReq.open("GET", "https://www.purpleair.com/json?show=13165");
      oReq.send();
    }
    loadData()
  </script>
</body>

</html>

答案 1 :(得分:0)

请注意,Stats属性在其他JSON编码结果的内部 中是JSON编码的。

这是另一种处理方法,使用更现代的fetch代替XHR:

const getData = () =>
  fetch('https://www.purpleair.com/json?show=13165')
    .then(res => res.json())
    .then(json => json.results)
    .then(res => res.map(r => JSON.parse(r.Stats)))
    .then(res => res.map(r => r.v))

getData()
  .then(vs => document.getElementById('output').innerHTML = vs)
#output {background: yellow; padding: .25em}
<h1>Test</h1>
<p>Stats v values: <span id="output"></span> 

更新:说明

一条评论询问其工作原理。

首先,不幸的是命名重叠。 resresultresults是服务器调用结果的通用名称。 res中的res => res.json()代表了这一点。但是然后我们采用了这个对象(坦白地说,我叫json,这不是一个很好的名字;它也可能应该是res,但我们已经有res个多余的对象)并且提取其results属性以传递到下一个.then()调用。我还将在下一个回调中将此变量称为res。最终,愚蠢地命名了最后一个通话.then()。它应该显示为

    .then(stats => stats.map(s => s.v))

所以它也可以写成

const getData = () =>
  fetch('https://www.purpleair.com/json?show=13165')
    .then(serverResponse => serverResponse.json())
    .then(apiResultObject => apiResultObject.results)
    .then(results => results.map(result => JSON.parse(result.Stats)))
    .then(stats => stats.map(stat => stat.v))

所有thenPromise API有关。如果您不习惯,那绝对值得花一些时间进行调查。

两个map调用用于通过收集在每个元素上运行给定函数的结果来将一个数组转换为另一个数组。所以

          results => results.map(result => JSON.parse(result.Stats))

表示对于数组results中的每个元素,我们将通过采用其Stats属性并对该值运行JSON.parse来创建一个新元素。然后,我们将所有这些值放到一个新数组中。 JSON.parse接受API返回的字符串值,并将其转换为JS对象。即使在响应对象上进行了JSON调用,我们也需要在这里进行此操作,因为该部分是经过双重编码的响应结构有些不寻常。

类似地,此行:

          stats => stats.map(stat => stat.v)

stats对象的数组转换为包含其v属性的数组。