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

AdonisJS多部分文件上传至S3失败问题求助

AdonisJS S3驱动多部分文件上传路由故障排查方案

问题背景

参照AdonisJS官方文档实现S3驱动直接文件上传,但接收多部分文件的路由无法正常运行,实现代码如下:

public async create({ request, response }: HttpContextContract) {
  try {
    await request.multipart
      .onFile(
        'file',
        {
          size: '900mb',
        },
        async (file, reportChunk) => {
          await Drive.putStream(`teste/${file.filename}`, file.file, {
              contentType: file.file.type,
              visibility: 'private',
            })
        }
      )
      .process()
    return response.ok(request.multipart.state)
  } catch (error) {
    console.log(error)
  }
}

排查与修复步骤

1. 验证S3驱动基础配置

  • 检查config/drive.ts中S3驱动的key、secret、region、bucket等参数是否正确,确保配置的IAM用户拥有S3桶的PutObject权限。
  • 先执行简单测试验证驱动可用性:
    // 在控制器或控制台中测试
    await Drive.put('test-upload.txt', 'test content', { visibility: 'private' })
    
    如果测试失败,先解决驱动配置问题,再调试上传逻辑。

2. 修正文件流与MIME类型处理

  • file.file.type并非可靠的MIME类型来源,部分客户端不会传递该值,建议从请求头获取:
    async (file, reportChunk) => {
      const contentType = file.headers['content-type'] || 'application/octet-stream'
      await Drive.putStream(`teste/${file.filename}`, file.file, {
        contentType,
        visibility: 'private',
      })
    }
    
  • 若流处理仍有问题,可尝试手动监听流的end事件确保完成,或使用管道方式:
    const writeStream = await Drive.getStreamWriter(`teste/${file.filename}`, {
      contentType: file.headers['content-type'] || 'application/octet-stream',
      visibility: 'private',
    })
    file.file.pipe(writeStream)
    await new Promise((resolve, reject) => {
      writeStream.on('finish', resolve)
      writeStream.on('error', reject)
    })
    

3. 完善错误反馈与日志

  • 原catch块仅打印错误,无法在客户端看到具体问题,修改为返回错误信息:
    catch (error) {
      console.error('文件上传失败详情:', error)
      return response.badRequest({ 
        message: '文件上传失败', 
        error: error.message,
        stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
      })
    }
    

4. 确认请求与路由配置

  • 确保前端请求使用multipart/form-data编码,且表单字段名严格为file(和onFile的第一个参数一致)。
  • 检查路由是否正确注册,例如:
    // routes.ts
    import Route from '@ioc:Adonis/Core/Route'
    Route.post('/uploads', 'UploadController.create')
    
  • 若启用了CSRF中间件,需确保上传请求在例外列表中(如SPA场景),修改config/shield.ts的csrf.enabledRoutes或exceptRoutes。

5. 调整大文件上传限制

  • 900MB的文件需要同步修改AdonisJS的body parser配置,编辑config/bodyparser.ts:
    export default {
      multipart: {
        maxSize: '900mb',
        processManually: true, // 因为我们手动调用了process()
      },
    }
    
  • 同时检查服务器(如Nginx、Apache)的配置,确保client_max_body_size(Nginx)或LimitRequestBody(Apache)设置为不小于900MB的值,避免请求被服务器提前拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:15:25