自定义Express API实现Spotify授权码流时Axios返回乱码问题
解决Spotify Token接口响应乱码问题
问题原因
Spotify的Token接口返回的响应默认采用gzip压缩格式,而Node.js环境下的axios不会自动解压这类压缩响应,直接读取response.data就会出现乱码。
修复方案
方案1:手动处理响应解压(无需额外依赖)
利用Node.js内置的zlib模块,对压缩响应进行手动解压:
const axios = require('axios'); const zlib = require('zlib'); const querystring = require('querystring'); router.get('/callback', (req,res) => { const authorizationCode = req.query.code || null; const state = req.query.state || null; axios({ method: 'post', url: 'https://accounts.spotify.com/api/token', data: querystring.stringify({ grant_type: 'authorization_code', code: authorizationCode, redirect_uri: redirect_uri, }), headers: { 'content-type': 'application/x-www-form-urlencoded', 'Accept-Encoding': 'gzip, deflate', // 告知服务器我们支持压缩格式 Authorization: `Basic ${new Buffer.from(`${client_id}:${client_secret}`).toString('base64')}`, }, responseType: 'arraybuffer', // 以二进制格式接收响应 }) .then(response => { if (response.status === 200) { // 根据响应头判断压缩类型并解压 const encoding = response.headers['content-encoding']; let decodedData; if (encoding === 'gzip') { decodedData = zlib.gunzipSync(response.data).toString('utf8'); } else if (encoding === 'deflate') { decodedData = zlib.inflateSync(response.data).toString('utf8'); } else { decodedData = response.data.toString('utf8'); } // 解析为JSON对象返回 res.send(JSON.parse(decodedData)); } else { res.send(response); } }) .catch(error => { res.send(error); }); });
方案2:使用第三方插件简化处理
安装axios-gzip插件自动处理压缩响应:
- 安装依赖:
npm install axios-gzip
- 修改代码启用插件:
const axios = require('axios'); const axiosGzip = require('axios-gzip'); const querystring = require('querystring'); // 为axios添加gzip解压支持 axiosGzip(axios); router.get('/callback', (req,res) => { const authorizationCode = req.query.code || null; const state = req.query.state || null; axios({ method: 'post', url: 'https://accounts.spotify.com/api/token', data: querystring.stringify({ grant_type: 'authorization_code', code: authorizationCode, redirect_uri: redirect_uri, }), headers: { 'content-type': 'application/x-www-form-urlencoded', Authorization: `Basic ${new Buffer.from(`${client_id}:${client_secret}`).toString('base64')}`, }, }) .then(response => { if (response.status === 200) { res.send(response.data); // 插件已自动完成解压和JSON解析 } else { res.send(response); } }) .catch(error => { res.send(error); }); });
额外检查点
- 确认
client_id和client_secret无拼写错误,格式正确 - 验证
redirect_uri与Spotify开发者后台配置的完全一致(包括协议、域名、路径) - 确保已正确引入
querystring模块(const querystring = require('querystring');)
内容的提问来源于stack exchange,提问作者Jayden Yu
相关产品推荐
相关产品推荐

