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

Azure部署的API上传图片至AWS S3时遇500内部服务器错误

问题:前端fetch调用Azure部署的API上传S3报500内部错误

项目架构

  • 前端:TypeScript、React,使用fetch()调用后端API(未使用axios)
  • 后端:C#、ASP.NET Core、Swagger UI,部署于Azure

问题详情

我正在实现一个通过自有API后端(部署在Azure)将图片上传至AWS S3存储桶的功能。使用Swagger UI测试上传API端点时一切正常,但通过前端fetch()调用同一端点时,出现以下500错误:

ImageUploadFunction.tsx:33     POST https://project.azurewebsites.net/api/files/upload 500 (Internal Server Error)

后端代码:FilesController.cs

using System.Threading.Tasks;
using Amazon.S3;
using Amazon.S3.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using API.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace API.Controllers
{
    [Route("api/files")]
    [ApiController]
    public class FilesController : BaseApiController
    {
        private readonly IAmazonS3 _s3Client;
        private readonly IOptions<AWSSecretsModel> awsSettings;
        private readonly IConfiguration _config;

        public FilesController(IAmazonS3 s3Client, IOptions<AWSSecretsModel> aws, IConfiguration config)
        {
            _s3Client = s3Client;
            awsSettings = aws;
            _config = config;
        }

        [HttpPost("upload")]
        public async Task<IActionResult> UploadFileAsync(IFormFile file)
        {
            if (file is null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            try 
            {
                var awsBucketName = awsSettings.Value.AWS_S3_BUCKET;
                var awsRegion = awsSettings.Value.AWS_REGION;

                // Upload the raw image to S3
                var bucketExists = await _s3Client.DoesS3BucketExistAsync(awsBucketName);
                if (!bucketExists) return NotFound($"Bucket {awsBucketName} does not exist.");

                var fileNameToPrefix = file.FileName;

                var request = new PutObjectRequest
                {
                    BucketName = awsBucketName,
                    Key = fileNameToPrefix,
                    InputStream = file.OpenReadStream()
                };
                await _s3Client.PutObjectAsync(request);

                return Ok($"File {file.FileName} [{fileNameToPrefix}] uploaded to S3 successfully!");
            }
            catch (ArgumentNullException ex)
            {
                return BadRequest(ex.Message);
            }
            catch (AmazonS3Exception ex)
            {
                return BadRequest($"Error uploading to S3: {ex.Message}");
            }
            catch (Exception ex)
            {
                return BadRequest($"Error: {ex.Message}");
            }
        }
    }
}

前端代码:ImageUploadFunction.tsx

import { useState, useEffect, ChangeEvent } from "react";

const API_URL = process.env.REACT_APP_API_URL;
const UPLOAD_URL = API_URL + `/api/files/upload`;

const ImageUpload: React.FC = () => {
    const [selectedImage, setSelectedImage] = useState<File | null>(null);
    const [uploading, setUploading] = useState(false);

    const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
        const files = event.target.files;
        if (files && files.length > 0) {
            setSelectedImage(files[0]);
        }
    };

    const handleImageUpload = async () => {
        if (!selectedImage) return;

        try {
            setUploading(true);

            const formData = new FormData();
            formData.append('file', selectedImage);

            const response = await fetch(UPLOAD_URL, {
                method: 'POST',
                body: formData,
            });

            if (response.ok) {
                console.log('Image uploaded successfully!');
            } else {
                console.error('Image upload failed!');
            }
        } catch (error) {
            console.error('Error uploading image:', error);
        } finally {
            setUploading(false);
        }
    };

    return (
        <div>
            <input type="file" onChange={handleFileChange} />
            <button onClick={handleImageUpload} disabled={!selectedImage || uploading}>
                {uploading ? 'Uploading...' : 'Upload Image'}
            </button>
        </div>
    );
};

export default ImageUpload;

排查情况

  • Swagger和Postman测试上传功能均正常,最初怀疑是前端问题,但未定位到具体原因
  • 补充1:后端处于开发环境时,前端通过https://localhost:5001/api/files/upload能成功上传;使用Azure线上地址发起请求则出现500错误,推测问题可能出在Azure配置上
  • 补充2:AWS S3存储桶策略及CORS配置如下:
    存储桶策略:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "PublicRead",
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:PutObject"
                ],
                "Resource": "arn:aws:s3:::mys3bucketname/*"
            }
        ]
    }
    
    CORS配置:
    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "GET",
                "PUT",
                "POST",
                "HEAD"
            ],
            "AllowedOrigins": [
                "*"
            ],
            "ExposeHeaders": []
        }
    ]
    
  • 补充3:后端代码已添加异常处理

希望各位提供解决建议。

内容的提问来源于stack exchange,提问作者malthe.w

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:52:33