从Javascript调用REST端点

时间:2018-06-17 14:05:59

标签: javascript rest

我试图从Javascript调用Spotify API,如下所示:

function callAPI() {
    var xhttp = new XMLHttpRequest();
    xhttp.open('GET', 'https://api.spotify.com/v1/search?q=Muse&type=track');
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.setRequestHeader('Authorization', 'Bearer <MY_ACCESS_TOKEN>');
    xhttp.send();
    var response = JSON.parse(xhttp.responseText);
}

但是,xhttp.responseText为空,但请求返回200。

我可以在浏览器中看到请求返回了预期的结果,但不知怎的,我无法从Javascript中提取它: enter image description here

我尝试使用Java调用REST端点(因为我对它更熟悉)并且有效:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Test {
    public static void main(String[] args) {
        System.out.println("blah");

        URL url = null;
        try {
            url = new URL("https://api.spotify.com/v1/search?q=Muse&type=track");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Authorization", "Bearer <MY_ACCESS_TOKEN>");
            String responseMessage = connection.getResponseMessage();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuffer content = new StringBuffer();

            try (reader) {
                String line;

                while ((line = reader.readLine()) != null) {
                    content.append(line);
                }
            } finally {
                reader.close();
            }
            System.out.println("Response: " + responseMessage);
            System.out.println("Content: " + content.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

我是一个Javascript新手,所以我做错了什么?非常感谢提前!

4 个答案:

答案 0 :(得分:2)

我从您的原始帖子中获取它,您更熟悉Java,因此在您的Javascript代码var response = JSON.parse(xhttp.responseText);中,您期望响应文本可用于解析。在Java中,代码可以正常工作,因为请求已发送,其余操作将被阻止,直到有响应为止。 Javascript没有遵循相同的范例,它不会等待响应,并且在从请求返回任何内容之前尝试解析xhttp.responseText

文档解释了这个XMLHttpRequest.responseText

  

在处理异步请求时,responseText的值始终具有从服务器接收的当前内容,即使它尚未完整,因为尚未完全接收到数据。

     

您知道,当readyState的值变为XMLHttpRequest.DONE(4)时,已收到整个内容,状态变为200(&#34; OK&#34;)。

因为Javascript不会等待响应,所以您的代码必须等待事件发出响应信号。这是其他海报所指的异步行为。文档here描述了如何创建将侦听响应事件的代码。 Boo Berr'ita提交的答案是一个很好的例子,使用您的代码。

答案 1 :(得分:1)

您忘记了onreadystatechange回调函数:

将结果包装在此函数中:

  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var response = JSON.parse(this.responseText);
    }
  };

答案 2 :(得分:1)

您可以在&#34;加载&#34;:

上添加事件处理程序
function onXHRLoad() {
  console.log(this.responseText);
}

function callAPI() {
    var xhttp = new XMLHttpRequest();
    xhttp.open('GET', 'https://api.spotify.com/v1/search?q=Muse&type=track');
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.setRequestHeader('Authorization', 'Bearer <MY_ACCESS_TOKEN>');
    xhttp.addEventListener('load', onXHRLoad);
    xhttp.send();
}

答案 3 :(得分:0)

非常感谢大家的回复,感谢您提醒我Javascript中的异步性,我完全忘记了这一点。我设法通过使用axios库来完成这项工作,我读到的库与Vue.js很好地集成,我打算使用它。以下是适用于我的解决方案:

<script>
import axios from "axios";
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: ''
    }
  },
  mounted() {
    axios({method: "GET", "url": "https://api.spotify.com/v1/search?q=Muse&type=track"}).then(result => {
      this.msg = result.data.tracks.items[0].name
  }, error => {
    console.error(error);
  });
  }
}
</script>