使用JavaScript向Shazam Core API POST音频文件遇422错误求助
问题分析与解决方案
你的422错误核心原因是当前代码未正确构造包含有效音频数据的请求体,导致API无法识别file字段:
- 你创建的
File对象是空的(第一个参数为[]),fileUri仅为文件路径而非实际音频二进制数据,导致FormData中的file字段无有效内容。 - 手动设置
Content-Type: application/octet-stream会覆盖FormData自动生成的multipart/form-data头,使得API无法解析表单中的file字段。
修复现有代码(优先推荐)
先解决核心问题,正确读取移动设备音频文件并构造请求:
// 需先通过对应框架API获取音频的Blob/ArrayBuffer数据 async function recognizeSong(fileBlob) { const url = 'https://shazam-core.p.rapidapi.com/v1/tracks/recognize'; const formData = new FormData(); // 传入实际Blob数据,可指定文件名 formData.append('file', fileBlob, 'audio.wav'); const options = { method: 'POST', headers: { 'X-RapidAPI-Key': 'MY_API_KEY', 'X-RapidAPI-Host': 'shazam-core.p.rapidapi.com' // 无需手动设置Content-Type,fetch会自动处理FormData的请求头 }, body: formData }; try { const response = await fetch(url, options); const result = await response.json(); console.log(result); return result; } catch (error) { console.error(error); } } // 示例:以Capacitor框架为例读取音频文件(根据你使用的环境调整) // import { Filesystem } from '@capacitor/filesystem'; // async function getAudioBlob(fileUri) { // const fileData = await Filesystem.readFile({ // path: fileUri, // encoding: 'base64' // }); // const byteArray = Uint8Array.from(atob(fileData.data), c => c.charCodeAt(0)); // return new Blob([byteArray], { type: 'audio/wav' }); // }
其他可行实现方法
方法1:使用XMLHttpRequest替代fetch
如果fetch在部分移动环境存在兼容性问题,可改用传统XHR:
function recognizeSongWithXHR(fileBlob) { const url = 'https://shazam-core.p.rapidapi.com/v1/tracks/recognize'; const formData = new FormData(); formData.append('file', fileBlob, 'audio.wav'); const xhr = new XMLHttpRequest(); xhr.open('POST', url); xhr.setRequestHeader('X-RapidAPI-Key', 'MY_API_KEY'); xhr.setRequestHeader('X-RapidAPI-Host', 'shazam-core.p.rapidapi.com'); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { const result = JSON.parse(xhr.responseText); console.log(result); } else { console.error('请求失败:', xhr.statusText); } }; xhr.onerror = function() { console.error('网络错误'); }; xhr.send(formData); }
方法2:直接发送二进制Blob(需确认API支持)
部分音频识别API支持直接发送二进制数据,可尝试去掉FormData直接传Blob:
async function recognizeSongDirectBlob(fileBlob) { const url = 'https://shazam-core.p.rapidapi.com/v1/tracks/recognize'; const options = { method: 'POST', headers: { 'X-RapidAPI-Key': 'MY_API_KEY', 'X-RapidAPI-Host': 'shazam-core.p.rapidapi.com', 'Content-Type': fileBlob.type // 比如audio/wav }, body: fileBlob }; try { const response = await fetch(url, options); const result = await response.json(); console.log(result); return result; } catch (error) { console.error(error); } }
关键注意事项
- 必须获取音频实际二进制数据:移动设备中的
fileUri仅为路径,需通过对应框架的文件读取API(如Capacitor Filesystem、Cordova File)将其转换为Blob/ArrayBuffer。 - 不要手动覆盖FormData的Content-Type:fetch会自动添加包含正确边界符的
multipart/form-data; boundary=xxx头,确保API能解析表单中的file字段。
内容的提问来源于stack exchange,提问作者Cristobal BL
相关产品推荐
相关产品推荐

