PHP/Laravel对接Azure TTS遇400错误:Data at the root level is invalid
Azure文本转语音(TTS)接口调用400错误排查求助
错误信息
-reasonPhrase: "Data at the root level is invalid. Line 1, position 1." -statusCode: 400
调用代码
$content = "I'm excited to try text to speech!"; $response = Http::withOptions([ 'debug'=>true, 'verify'=>false, ])->withToken($this->getTTSAuthToken())->withHeaders([ 'Content-Type' => 'application/ssml+xml', 'X-Microsoft-OutputFormat' => 'riff-24khz-16bit-mono-pcm', 'User-Agent' => 'content-development', 'Content-Length' => strlen($content), ])->post("https://eastus.tts.speech.microsoft.com/cognitiveservices/v1", "<speak version='1.0' xml:lang='en-US'><voice xml:lang='en-US' xml:gender='Male' name='en-US-ChristopherNeural'>$content</voice></speak>" );
问题说明
用PHP/Laravel/Inertia对接Azure TTS服务,连续几天碰到这个400错误,提示根级别数据无效。查Azure文档知道400对应参数问题,但已经按要求传了所有必要参数,试了好几种写法还是不行,求帮忙定位问题。
排查建议
- 修正Content-Length计算:当前用
strlen($content)算的是文本内容长度,但实际提交的是完整SSML字符串,应该计算整个SSML的长度,或者直接删掉这个Header——Laravel Http客户端会自动处理Content-Length,手动设置反而容易出错。 - 检查SSML格式:
- 把SSML里的单引号换成双引号,比如
version="1.0",避免XML解析歧义; - 确保
$content里没有未转义的特殊字符(比如&、<、>),有就换成XML实体(&、<、>)。
- 把SSML里的单引号换成双引号,比如
- 验证令牌有效性:确认
getTTSAuthToken()返回的令牌在有效期内(Azure TTS令牌默认10分钟过期),过期会导致接口异常。 - 简化请求选项:暂时去掉
debug和verify选项,尤其是verify=>false可能干扰请求流程,或者用curl直接调用接口测试,对比请求差异。
内容的提问来源于stack exchange,提问作者xyLuz
相关产品推荐
相关产品推荐

