【问题标题】:Calling REST endpoint from Javascript从 Javascript 调用 REST 端点
【发布时间】:2018-11-26 14:07:09
【问题描述】:

我正在尝试像这样从 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 中提取它:

我尝试使用 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 新手,我做错了什么?提前非常感谢!

【问题讨论】:

标签: javascript rest


【解决方案1】:

非常感谢大家的回复,感谢您提醒我 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>

【讨论】:

    【解决方案2】:

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

    文档解释了这个XMLHttpRequest.responseText

    在处理异步请求时,responseText 的值始终包含从服务器接收到的当前内容,即使由于尚未完全接收到数据而不完整。

    当readyState的值变成XMLHttpRequest.DONE(4),status变成200(“OK”)时,你就知道整个内容已经收到了。

    因为 Javascript 不会等待响应,所以您的代码必须等待一个事件来表明响应已经做出。这是其他张贴者所指的异步行为。文档here 描述了如何创建将侦听响应事件的代码。 Boo Berr'ita 提交的答案就是一个很好的例子,使用你的代码。

    【讨论】:

      【解决方案3】:

      您可以在“加载”上添加事件处理程序:

      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();
      }
      

      【讨论】:

        【解决方案4】:

        你忘记了onreadystatechange 回调函数:

        只需将结果包装在此函数中即可:

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

        【讨论】:

          猜你喜欢
          • 2019-09-02
          • 1970-01-01
          • 1970-01-01
          • 2018-02-28
          • 1970-01-01
          • 1970-01-01
          • 2018-11-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多