使用Axios实现Spotify授权码流回调,令牌端点返回编码数据
问题:Spotify授权码流回调中Axios返回编码内容,无法获取JSON响应
问题背景
我正在开发调用Spotify API的应用,实现授权码流认证的回调环节时遇到问题(已在Spotify应用中注册回调URL)。回调路由代码与教程及示例一致,使用Axios作为HTTP库,但返回的响应数据是编码后的乱码,无法解析成JSON以获取access_token等字段。
Axios问题代码
app.get("/callback", (req, res) => { const code = req.query.code || null; const usp = new URLSearchParams({ code: code, redirect_uri: REDIRECT_URI, grant_type: "authorization_code", }); axios({ method: "post", url: "https://accounts.spotify.com/api/token", data: usp, headers: { "content-type": "application/x-www-form-urlencoded", Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`, }, }) .then(response => { console.log(response.status); // 输出200 console.log(response.data); // 输出编码后的字符串 if (response.status === 200) { res.send(JSON.stringify(response.data)) } else { res.send(response); } }) .catch((error) => { res.send(error); });
异常现象
响应状态码为200,但response.data返回类似如下的编码字符串:
"\u001f�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0003E�˒�0\u0000Ee�uS\u0015��\u000e�(\b\u0012h\u0005tC%\u0010\u0014T\u001e�����0��^:���p\u0014Ѻ\u000e��Is�7�:��\u0015l��ᑰ�g�����\u0"
尝试Base64解码无效,无法正常打印或获取access_token等预期字段。想知道是否可以给Axios传递参数,强制指定响应为JSON格式?
对比:Request库可正常运行的代码
改用npm的request包并传入json: true参数后,能正常获取有效令牌,代码如下:
app.get('/callback', function(req, res) { // 申请刷新令牌和访问令牌 // 先检查state参数 const code = req.query.code || null; const state = req.query.state || null; const storedState = req.cookies ? req.cookies[stateKey] : null; res.clearCookie(stateKey); const authOptions = { url: 'https://accounts.spotify.com/api/token', form: { code: code, redirect_uri: REDIRECT_URI, grant_type: 'authorization_code', }, headers: { Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`, }, json: true, }; request.post(authOptions, function (error, response, body) { if (!error && response.statusCode === 200) { const access_token = body.access_token; const refresh_token = body.refresh_token; var options = { url: 'https://api.spotify.com/v1/me', headers: { Authorization: 'Bearer ' + access_token }, json: true, }; // 使用访问令牌调用Spotify Web API request.get(options, function(error, response, body) { console.log(body); }); // 也可以将令牌传递到浏览器,从前端发起请求 res.redirect('/#' + querystring.stringify({ access_token: access_token, refresh_token: refresh_token, })); } else { res.redirect(`/#${querystring.stringify({ error: 'invalid_token' })}`); } }); });
内容的提问来源于stack exchange,提问作者Andy J.
相关产品推荐
相关产品推荐

