You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS调用Azure长音频文本转语音API的JS等效代码问题

报错原因

返回Unsupported Media Type是两个核心写法错误导致的:

  • node-fetch 原生不支持直接传files、payload这类自定义字段。Python的requests库会自动完成多部分表单(multipart/form-data)的格式拼装,node-fetch 需要手动通过FormData对象构造符合格式的请求体
  • 手动设置了Content-Type: application/json。同时传输结构化参数和文件必须使用multipart/form-data格式,且不能手动写死这个请求头:合法的multipart头需要携带随机生成的boundary分隔符,手动写头会丢失这个参数,服务端无法正常解析请求内容。
可直接运行的实现代码

首先确认依赖:

  • Node 18及以上版本自带原生fetch、FormData实现,无需额外安装依赖
  • 低于18版本的Node需要先安装依赖:npm i node-fetch@2 form-data

完整代码如下:

const fs = require('fs');
const path = require('path');
// Node 18+ 可注释掉下面两行依赖引入
const fetch = require('node-fetch');
const FormData = require('form-data');

async function submitAzureTtsTask() {
  // 替换为你自己的配置
  const requestUrl = '你的Azure长文本转语音接口地址';
  const subscriptionKey = '你的Ocp-Apim-Subscription-Key';
  const scriptPath = '你的txt脚本文件路径,例:./input.txt';

  // 业务参数和Python示例完全对齐
  const ttsConfig = {
    displayname: 'long audio synthesis sample',
    description: 'sample description',
    locale: 'en-US',
    voices: [{ voicename: '你要使用的语音名称' }],
    outputformat: 'riff-16khz-16bit-mono-pcm',
    concatenateresult: true
  };

  // 构造多部分表单
  const form = new FormData();
  // 追加配置JSON字段,指定内容类型为application/json
  form.append('config', JSON.stringify(ttsConfig), {
    contentType: 'application/json'
  });
  // 追加txt脚本文件,和Python示例的script字段对应
  const scriptFileName = path.basename(scriptPath);
  const scriptStream = fs.createReadStream(scriptPath);
  form.append('script', scriptStream, {
    filename: scriptFileName,
    contentType: 'text/plain'
  });

  // 发送请求,不要手动设置Content-Type,用form自动生成的带boundary的合法头
  const res = await fetch(requestUrl, {
    method: 'POST',
    headers: {
      'Ocp-Apim-Subscription-Key': subscriptionKey,
      ...form.getHeaders()
    },
    body: form
  });

  if (!res.ok) {
    const errMsg = await res.text();
    throw new Error(`请求失败,状态码${res.status}:${errMsg}`);
  }
  const taskInfo = await res.json();
  console.log('合成任务提交成功:', taskInfo);
  return taskInfo;
}

submitAzureTtsTask().catch(err => console.error(err));
关键注意点
  • 读文件优先用fs.createReadStream而不是readFileSync:大体积脚本文件用流传输不会占用过高内存,和Python示例中open()返回的文件对象行为一致
  • Azure长文本转语音接口要求JSON配置作为multipart表单中名为config的part传入,不是直接把JSON序列化为整个请求体
  • node-fetch的请求配置对象不存在files、payload属性,所有请求内容都需要通过body字段传递

内容的提问来源于stack exchange,提问作者sebagl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:51:28