安卓设备FormData有效,而IOS设备接口报错?

const audioToText = async (blob: Blob) => {
    const file = new File([blob], `${Date.now()}.mp3`, {
      type: 'audio/mp3'
    });
    const formData: any = new FormData();
    formData.append('file', file);
    formData.append('user', account.user);
    // 查看formData内容
    for (let [key, value] of formData.entries()) {
      if (value instanceof File) {
        console.log(`${key}: File - ${value.name}, ${value.size} bytes, ${value.type}`);
      } else {
        console.log(`${key}: ${value}`);
      }
    }
    let res: any = await audioToTextAPI(formData);
};

通过前端录音拿到blob,然后转file添加FormData,到这个请求在安卓、PC设备都是正常的,而ios设备接口报错了
image.png
尝试过的方法:
1、在main.js中使用import 'formdata-polyfill/formdata.min.js';无效

在ios设备中MediaRecorder.isTypeSupported查询audio/webm格式是支持的。

console.log('支持类型:audio/webm', MediaRecorder.isTypeSupported('audio/webm;codecs=opus'));

image.png

另外,axios也没有手动设置content-type

service.interceptors.request.use(
  function (config: any) {
    config.headers.Authorization = import.meta.env.VITE_APP_ID;
    return config;
  },
  function (error: any) {
    // 请求错误
    return Promise.reject(error);
  }
);
阅读 894
1 个回答

我把你的代码改了一下:
1.删除了File对象创建 - 不再使用 new File([blob], fileName, {type: 'audio/mp3'})
2.直接使用blob - formData.append('file', blob, fileName)
3.文件名改为webm - 因为确认iOS支持这个格式
4.添加了备用方案 - 如果还是失败会自动尝试重建blob

const audioToText = async (blob: Blob) => {
  try {
    console.log('🎧 音频信息:', {
      size: blob.size,
      type: blob.type,
      isIOS: /iPad|iPhone|iPod/.test(navigator.userAgent)
    });

    // 🛠 如果类型不正确则修复
    if (blob.type !== 'audio/webm') {
      blob = new Blob([blob], { type: 'audio/webm' });
    }

    // 📤 构造上传数据
    const formData = new FormData();
    formData.append('file', blob, `${Date.now()}.webm`);
    formData.append('user', account.user);

    // 🧾 打印表单内容用于调试
    for (let [key, value] of formData.entries()) {
      if (value instanceof Blob) {
        console.log(`${key}: Blob - size: ${value.size}, type: ${value.type}`);
      } else {
        console.log(`${key}: ${value}`);
      }
    }

    // 🚀 发起请求
    const res = await audioToTextAPI(formData);
    return res;

  } catch (error) {
    console.error('❌ 上传失败:', error?.message || error);

    try {
      console.log('🧪 尝试重建 blob...');
      const arrayBuffer = await blob.arrayBuffer();
      const newBlob = new Blob([arrayBuffer], { type: 'audio/webm' });

      const formData = new FormData();
      formData.append('file', newBlob, `${Date.now()}.webm`);
      formData.append('user', account.user);

      const res = await audioToTextAPI(formData);
      return res;

    } catch (fallbackError) {
      console.error('💥 重建方案也失败:', fallbackError?.message || fallbackError);
      throw fallbackError;
    }
  }
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题