前端JS调用Whisper音频转录接口遇网络错误问题排查
前端请求OpenAI音频转录接口返回200但无法获取响应的问题解决
问题背景
我有一段可正常运行的NodeJS代码,能向本地部署的OpenAI API的/audio/transcriptions端点发起请求,通过fs.createReadStream("speech.m4a")传入文件,可正常返回{text: "<语音转录内容>"}。
但改用前端输入框选择文件发起相同请求时,无论是Axios还是Fetch都会报错:Axios报Network error,Fetch报TypeError: Failed to fetch。不过后端日志显示请求已处理完成,接口返回状态码200 OK。
尝试的Axios代码
const API_URL = "http://172.26.175.134:8080/openai/v1/audio/transcriptions"; const fileInput = document.getElementById("file-input"); fileInput.onchange = () => { const files = fileInput.files; //if no file is selected if (files.length === 0) { alert("Please select a file!"); return; } const selectedFile = files[0]; const reader = new FileReader(); reader.onload = (e) => { axios .post( API_URL, { file: new File([e.target.result], { type: selectedFile.type }), model: "whisper", language: "en", temperature: 1, prompt: "", }, { headers: { "Content-Type": "multipart/form-data", }, } ) .then((response) => { console.debug(response.data); }) .catch((error) => { console.error("Error:", error); }); }; reader.readAsArrayBuffer(selectedFile); };
尝试的Fetch代码
reader.onload = async (e) => { const body = new FormData(); body.append( "file", new File([e.target.result], { type: selectedFile.type }) ); body.append("model", "whisper"); body.append("language", "en"); body.append("temperature", "1"); body.append("prompt", ""); await fetch(API_URL, { method: "POST", body: body, }) .then((res) => { console.debug(res); }) .catch((err) => { console.debug(err); }); };
后端日志
INFO: 172.26.160.1:62548 - "POST /openai/v1/audio/transcriptions HTTP/1.1" 200 OK INFO:faster_whisper:Processing audio with duration 00:19.925 INFO:faster_whisper:Detected language 'en' with probability 1.00 INFO:__main__:Completed /tmp/tmpswy0__ru INFO:__main__:Transcription complete!
问题成因
- CORS配置缺失:前端浏览器受同源策略限制,即使后端返回200,若未配置正确的CORS响应头,浏览器会直接拦截响应内容,导致无法获取。
- 冗余的FileReader处理:无需将File对象转为ArrayBuffer再重新构造File,多余的转换可能引发数据格式异常。
- Axios请求头设置错误:手动设置
"Content-Type": "multipart/form-data"会覆盖Axios自动生成的带边界标识的请求头,可能导致后端解析异常(虽然后端处理了请求,但浏览器仍会因响应头问题拦截)。 - Fetch未解析响应内容:原Fetch代码仅打印了Response对象,未执行解析操作,无法获取实际返回的转录数据。
解决方案
步骤1:修复后端CORS配置
在本地部署的OpenAI API服务中添加CORS响应头,允许前端所在域的请求。以FastAPI框架为例:
from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], # 生产环境替换为前端实际域名 allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
其他后端框架需配置对应CORS规则,确保响应包含Access-Control-Allow-Origin等必要头。
步骤2:简化前端请求代码
优化后的Axios代码
const API_URL = "http://172.26.175.134:8080/openai/v1/audio/transcriptions"; const fileInput = document.getElementById("file-input"); fileInput.onchange = () => { const files = fileInput.files; if (files.length === 0) { alert("请选择文件!"); return; } const selectedFile = files[0]; const formData = new FormData(); formData.append("file", selectedFile); formData.append("model", "whisper"); formData.append("language", "en"); formData.append("temperature", "1"); formData.append("prompt", ""); axios.post(API_URL, formData) .then((response) => { console.debug(response.data); }) .catch((error) => { console.error("错误:", error); }); };
优化后的Fetch代码
const API_URL = "http://172.26.175.134:8080/openai/v1/audio/transcriptions"; const fileInput = document.getElementById("file-input"); fileInput.onchange = async () => { const files = fileInput.files; if (files.length === 0) { alert("请选择文件!"); return; } const selectedFile = files[0]; const formData = new FormData(); formData.append("file", selectedFile); formData.append("model", "whisper"); formData.append("language", "en"); formData.append("temperature", "1"); formData.append("prompt", ""); try { const res = await fetch(API_URL, { method: "POST", body: formData, }); const data = await res.json(); // 解析响应为JSON格式 console.debug(data); } catch (err) { console.debug("错误:", err); } };
关键优化点
- 移除冗余的FileReader操作,直接使用
fileInput.files[0]原生File对象 - Axios无需手动设置
Content-Type,框架会自动生成符合multipart/form-data规范的请求头 - Fetch添加
res.json()步骤,解析后端返回的JSON格式转录数据
内容的提问来源于stack exchange,提问作者nagytoth1
相关产品推荐
相关产品推荐

