我试图从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新手,所以我做错了什么?非常感谢提前!
答案 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>