Delphi XE10中用Indy TIdHTTP调用微软语音识别API POST请求报400错误求助
解决Delphi XE10中TIdHTTP调用微软语音识别API返回400 Bad Request的问题
遇到400 Bad Request错误,通常意味着你的请求格式、参数或者数据不符合微软语音识别API的要求。结合Delphi XE10 + Indy的场景,我整理了几个最常见的问题点,你可以逐一排查:
1. 请求头缺失或参数错误
微软语音识别API对请求头有严格要求,少了关键头或者参数写错都会直接返回400。你必须确保以下几个头正确设置:
- Ocp-Apim-Subscription-Key:你的认知服务订阅密钥,必须放在请求头里(不能放在URL参数中)
- Content-Type:必须指定音频格式,比如PCM 16位、16kHz单声道的WAV文件,格式为
audio/wav; codec="audio/pcm"; samplerate=16000,注意这里的samplerate、codec参数不能写错 - Accept:建议指定为
application/json,方便接收结构化的响应
对应的Delphi代码示例:
IdHTTP1.Request.ContentType := 'audio/wav; codec="audio/pcm"; samplerate=16000'; IdHTTP1.Request.CustomHeaders.Add('Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'); IdHTTP1.Request.Accept := 'application/json';
2. 音频数据不符合格式要求
微软API只接受特定格式的音频:16位PCM、16kHz采样率、单声道的WAV文件。如果你的音频是其他格式(比如MP3、8kHz采样、立体声),即使请求头写对了,也会返回400。
你可以用音频编辑工具(比如Audacity)转换音频格式,确保符合要求。在代码中,要直接传递音频流,不要把音频数据转成字符串再发送:
var AudioStream: TFileStream; Response: string; begin // 确保test.wav是符合要求的音频文件 AudioStream := TFileStream.Create('test.wav', fmOpenRead or fmShareDenyWrite); try // 手动设置Content-Length,避免Indy自动处理时出现偏差 IdHTTP1.Request.ContentLength := AudioStream.Size; // 替换为你订阅对应的区域端点(比如eastasia、westus等) Response := IdHTTP1.Post('https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US', AudioStream); ShowMessage('识别结果:' + Response); finally AudioStream.Free; end; end;
3. HTTPS配置不正确
因为调用的是HTTPS接口,你需要确保Indy的SSL组件配置正确:
- 给TIdHTTP的
IOHandler属性分配一个TIdSSLIOHandlerSocketOpenSSL组件 - 在
TIdSSLIOHandlerSocketOpenSSL的SSLVersions属性中勾选sslvTLSv1_2(微软API要求TLS 1.2及以上版本) - 确保你的程序目录下有匹配版本的OpenSSL DLL文件(XE10对应的Indy通常需要
libeay32.dll和ssleay32.dll,或者新版本的libcrypto-1_1.dll、libssl-1_1.dll,注意32位/64位要和你的程序编译架构一致)
如果SSL配置错误,可能会导致请求无法正确发送,间接返回400错误。
4. API端点URL错误
微软语音识别API的端点是分区域的,比如westus、eastasia、northeurope等,你必须使用和你订阅密钥对应的区域端点,否则会返回400或401错误。可以在Azure门户的认知服务资源页面查看对应的端点URL。
另外,URL中的language参数格式要正确(比如en-US、zh-CN),不能拼写错误。
5. 排查技巧:抓包对比请求
如果以上都检查过还是有问题,建议用Fiddler或者Wireshark抓包,把你的请求和微软官方文档中的示例请求对比,看以下几点:
- 请求头是否完全匹配
- Content-Length是否和音频数据大小一致
- 音频数据是否正确传递(没有被篡改或编码错误)
内容的提问来源于stack exchange,提问作者Ingo
相关产品推荐
相关产品推荐

