我的项目设置如下:
前端- TypeScript,React,fetch()
用于调用我的后端API,而不是axios。
后端- C#、ASP.NET Core、Swagger UI、Azure
我正在尝试通过部署在Azure上的我自己的API后端实现一个简单的图像文件上传功能到我的S3存储桶。当我用Swagger UI测试 just 用于上传的API端点时,它可以正常工作,没有任何问题。但是,当我尝试使用fetch()
从前端调用同一个端点时,我得到以下错误:
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一切正常,我觉得这个问题与我的前端有关,尽管有错误消息。我只是不知道我做错了什么。
有什么建议吗?
编辑:
我刚刚注意到,我只能通过localhost成功上传图像文件,当我在其开发环境中运行我的后端时(https://localhost:5001/api/files/upload)。尝试通过我的实时应用URL(https://project.azurewebsites.net/api/files/upload)进行POST调用时,我遇到了500内部服务器错误。所以我的问题肯定在于我的Azure配置,对吗?
编辑2:
下面是我的存储桶策略以及我的S3存储桶的CORS配置。
Bucket策略:
{
"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:**根据注解中的建议,在后端代码(FilesController.cs)中添加了异常处理。
1条答案
按热度按时间zmeyuzjn1#
这并不是真正解决实际问题的解决方案,但我决定改用AWS Elastic Beanstocks,因为我所有的其他服务都由AWS托管。我已经可以透露,在直接将后端部署到EBS后,我的上传端点工作起来就像一个魅力。
然而,正如Derpirscher和Marc Campora所指出的,在端点中提供异常处理来显示可能发生的事情可以(老实说应该)指出正确的方向。在我的情况下,虽然,这并没有帮助我任何进一步,所以我只是决定咬紧牙关,离开Azure。
我仍然保留所有与Azure相关的代码,所以我很乐意将这个问题留给其他任何人来提出建议/解决方案,我会尝试实现它们。以防万一其他人也会偶然发现这个问题。