这里是我用JavaScript实现的方法。像你提到的那样,使用全局变量:
var access_token = null;
我的URL看起来像这样:
https://...home.jsp#access_token=BQAXe5JQOV_xZmAukmw6G430lreF......rQByzZMcOIF2q2aszujN0wzV7pIxA4viMbQD6s&token_type=Bearer&expires_in=3600&state=vURQeVAoZqwYm4dC
在Spotify将用户重定向到您在仪表板上指定的URI后,我解析带有访问令牌的哈希URL,如下所示:
var hash = window.location.hash.substring(1);
var accessString = hash.indexOf("&");
access_token = hash.substring(13, accessString);
console.log("Access Token: " + access_token);
输出结果如下:
访问令牌:BQAXe5JQOV_xZmAukmw6G430lreF...........rQByzZMcOIF2q2aszujN0wzV7pIxA4viMbQD6s
我在sessionStorage中保存此访问令牌,以防用户离开页面且url不包含access_token。我假设这是隐式授权流程,因为您想要使用纯JavaScript。只需确保每小时重新获取一次access token,因为它们会过期。
补充说明
我可以向您展示如何在示例中获取令牌并使用它。
我在.html页面上有一个按钮,点击该按钮会调用名为implicitGrantFlow()的函数,该函数位于名为Test.js的JavaScript文件中。
function implicitGrantFlow() {
if (sessionStorage.getItem("accessToken") !== null &&
sessionStorage.getItem("tokenTimeStamp") !== null &&
upTokenTime < tokenExpireSec) {
var timeLeft = (tokenExpireSec - upTokenTime);
console.log("Token still valid: " + Math.floor(timeLeft / 60) + " minutes left.");
$(location).attr('href', "home.jsp");
} else {
console.log("Token expired or never found, getting new token.");
$.ajax({
url: auth_url,
type: 'GET',
contentType: 'application/json',
data: {
client_id: client_id,
redirect_uri: redirect_uri,
scope: scopes,
response_type: response_type_token,
state: state
}
}).done(function callback(response) {
console.log("COULD THIS BE A SUCCESS?");
$(location).attr('href', this.url);
}).fail(function (error) {
console.log("ERROR HAPPENED: " + error.status);
console.log(this.url);
$(location).attr('href', this.url);
});
}
我正在做的是检查我在sessionStorage中存储的access_token信息是否为空。我使用时间戳生成令牌创建时间和理论上到期时间。如果这些参数满足条件,那么我不会再进行另一个调用。
否则,我将调用以获取访问令牌,如果成功,将重定向到我在先前写的URI(你会看到我在.fail部分中设置了重定向。这是因为我在学校服务器上没有权限设置绕过CORS相关问题的设置,即使我创建的重定向url没问题.)。
然后当我的白名单URI加载(重定向到我的主页)时,我利用我的标签。
home.jsp
<body onload="getAccessToken()">
在我的<tag>标签中,我有一个调用函数的方法,使页面加载一次。这会调用函数getAccessTokens()。
function getAccessToken() {
access_token = sessionStorage.getItem("accessToken");
if (access_token === null) {
if (window.location.hash) {
console.log('Getting Access Token');
var hash = window.location.hash.substring(1);
var accessString = hash.indexOf("&");
access_token = hash.substring(13, accessString);
console.log("Access Token: " + access_token);
if (typeof(Storage) !== "undefined") {
sessionStorage.setItem("accessToken", access_token);
sessionStorage.setItem("tokenTimeStamp", secondsSinceEpoch);
sessionStorage.setItem("tokenExpireStamp", secondsSinceEpoch + 3600);
console.log("Access Token Time Stamp: "
+ sessionStorage.getItem("tokenTimeStamp")
+ " seconds\nOR: " + dateNowMS + "\nToken expires at: "
+ sessionStorage.getItem("tokenExpireStamp"));
} else {
alert("Your browser does not support web storage...\nPlease try another browser.");
}
} else {
console.log('URL has no hash; no access token');
}
} else if (upTokenTime >= tokenExpireSec) {
console.log("Getting a new acess token...Redirecting");
sessionStorage.clear();
$(location).attr('href', 'index.html');
} else {
var timeLeft = (tokenExpireSec - upTokenTime);
console.log("Token still valid: " + Math.floor(timeLeft / 60) + " minutes left.");
}
在我从url中获取访问令牌后,我将令牌存储在会话存储中。 我使用了早期帖子中提到的过程,但是这里是完整的JavaScript代码。 如果在注释之后仍然不清楚,请告诉我。
现在我们已经获取并存储了访问令牌,我们现在可以进行api调用。 这是我的做法(我一直在使用qQuery,以下是获取用户顶部曲目的示例)。
示例api调用
function getUserTopTracks(time_range, offset, limit) {
$.get({
url: 'https://api.spotify.com/v1/me/top/tracks',
headers: {
'Authorization': 'Bearer ' + access_token,
},
data: {
limit: limit,
offset: offset,
time_range: time_range
},
success: function (response) {
res = JSON.parse(JSON.stringify(response.items));
for (i = 0; i < res.length; i++) {
console.log("Track: " + res[i]);
}
},
fail: function () {
console.log("getUserTopTracks(): api call failed!");
}
});
参数time_range被指定为“long_term”,以获取用户从一开始就喜欢的顶级曲目(有关更多信息,请查阅Spotify的文档),此外,偏移量为0以从头开始,并且限制为50,因为这是每次调用的最大获取数量。
成功后,我的响应变量'response'中的根要从“items”部分开始解析,以使解析更容易(您不必这样做,您可以简单地使用response.xxx.items.xxx)。然后我将响应打印到控制台中。
这是您可以做的基本操作,您决定如何处理数据或存储数据取决于您。我不是专家,我仅在上个学期开始学习Web编程,我所做的许多实践可能是错误或不正确的。