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

FastAPI POST请求异常:前端fetch提前抛出错误

问题解决建议

核心问题分析

你遇到的情况是后端处理耗时过长时前端提前抛出异常,主要有两个关键原因:

  • 前端Fetch API的响应解析方式错误
  • 后端异步端点中调用阻塞性同步函数,导致事件循环被阻塞,请求被提前中断

具体修复步骤

1. 修复前端fetch的响应解析错误

你的前端代码中直接使用response.data是错误的(这是Axios的语法),Fetch API需要调用response.json()方法来异步解析JSON响应。修改后的代码:

async function processImages() {
    const fileInput = document.getElementById('fileInput');
    const outputImagesDiv = document.getElementById('outputImages');

    const files = fileInput.files;
    if (files.length === 0) {
        alert('Please select at least one image.');
        return;
    }

    const formData = new FormData();
    for (const file of files) {
        formData.append('files', file);
    }

    try {
        const response = await fetch('http://127.0.0.1:3003/process_images', {
            method: 'POST',
            body: formData,
        });

        if (!response.ok) { // 更通用的响应成功判断逻辑
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const result = await response.json(); // 修复解析方式
        outputImagesDiv.innerHTML = '';

        for (let i = 0; i < result.imagesWithLandmarks.length; i++) {
            const imgElement = document.createElement('img');
            imgElement.src = `data:image/png;base64,${result.imagesWithLandmarks[i]}`;
            outputImagesDiv.appendChild(imgElement);
        }
    } catch (error) {
        console.error('Error:', error);
        alert('An error occurred while processing images.');
    }
}

2. 解决后端阻塞问题

你的FastAPI端点用了async def,但里面调用了耗时的同步函数dlib.process_images,这会阻塞FastAPI的事件循环,导致请求被服务器或浏览器提前中断。有两种修复方式:

方式一:改用同步端点(推荐)

FastAPI会自动将同步端点放到线程池中执行,不会阻塞事件循环:

@app.post("/process_images")
# 把async def改成def
def process_images(files: List[UploadFile] = File(...)):
    image_paths = []
    for file in files:
        with open(f"./uploads/{file.filename}", "wb") as buffer:
            buffer.write(file.file.read())
        image_paths.append(f"./uploads/{file.filename}")

    result = dlib.process_images(image_paths)

    return result.dict()

方式二:用asyncio.to_thread包装同步函数

如果必须保留异步端点,将同步函数放到线程池运行:

import asyncio

@app.post("/process_images")
async def process_images(files: List[UploadFile] = File(...)):
    image_paths = []
    for file in files:
        with open(f"./uploads/{file.filename}", "wb") as buffer:
            buffer.write(file.file.read())
        image_paths.append(f"./uploads/{file.filename}")

    # 将同步函数放到线程池执行,避免阻塞事件循环
    result = await asyncio.to_thread(dlib.process_images, image_paths)

    return result.dict()

3. 延长服务器超时时间

如果模型处理时间超过Uvicorn默认的60秒超时,启动服务器时需要增加超时参数:

uvicorn main:app --host 127.0.0.1 --port 3003 --timeout-keep-alive 300 --timeout-graceful-shutdown 300

这里设置为300秒(5分钟),可根据实际处理时间调整。

4. 前端添加显式超时处理

手动给fetch添加超时逻辑,避免无限制等待:

// 封装带超时的fetch函数
async function fetchWithTimeout(resource, options = {}) {
    const { timeout = 300000 } = options; // 默认5分钟超时
    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), timeout);
    
    try {
        const response = await fetch(resource, {
            ...options,
            signal: controller.signal
        });
        clearTimeout(id);
        return response;
    } catch (error) {
        clearTimeout(id);
        throw error;
    }
}

// 在processImages中使用
async function processImages() {
    // ... 其他代码不变
    try {
        const response = await fetchWithTimeout('http://127.0.0.1:3003/process_images', {
            method: 'POST',
            body: formData,
            timeout: 300000 // 5分钟
        });
        // ... 后续解析逻辑
    } catch (error) {
        // 区分超时和其他错误
        if (error.name === 'AbortError') {
            console.error('Request timed out');
            alert('Processing timed out, please try again.');
        } else {
            console.error('Error:', error);
            alert('An error occurred while processing images.');
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:00:57