Asp.Net Core API CORS政策错误仅在文件上传中 [英] Asp.Net Core API CORS policy error only in file upload
问题描述
仅当使用AspNet Core API 3.1将文件上传到服务器时,我才出现CORS策略阻止错误.以不同的方式将cors策略添加到启动并使用自定义中间件不能解决我的问题.
I have CORS Policy blocking error only while uploading file to server using AspNet Core API 3.1. Adding cors policy to startup in different ways and using custom middleware not solved my problem.
启动:
//ConfigureServices
// ConfigureServices
services.AddCors(options =>
{
options.AddPolicy("EnableSVCCors", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.Build();
});
});
//配置
app.UseCors("EnableSVCCors");
通过从React Client网站调用所有API方法都可以正常工作,但是在尝试上传图片时出现以下错误:
All API methods working fine by calling from react client web site but while trying to upload image I have following error:
在以下位置访问XMLHttpRequest" http://172.16.1.34:1980/api/accounts/uploadAvatar 起源" http://172.16.1.35:3000 "已被CORS政策禁止:否请求中存在"Access-Control-Allow-Origin"标头资源.
Access to XMLHttpRequest at 'http://172.16.1.34:1980/api/accounts/uploadAvatar' from origin 'http://172.16.1.35:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我还尝试如下更改cors政策,但无法正常工作:
I also try to change cors policy as below but not working:
services.AddCors(options =>
{
options.AddPolicy("EnableSVCCors", builder =>
{
builder
.WithOrigins("http://172.16.1.35:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.Build();
});
});
注意:调用 http://172.16.1.34:1980/api/accounts/uploadAvatar 使用PostMan并发送base64字符串作为图像可以正常工作!因此,对要保存图像的文件夹的访问限制没有问题.
Note: Calling http://172.16.1.34:1980/api/accounts/uploadAvatar using PostMan and sending base64 string as image is working fine! So there is no problem with access limits on folder where image going to be saved.
我还尝试如下添加自定义中间件,但目前还无法正常工作:
I also tried to add custom middleware as below but not working as yet:
public class CorsMiddleWare
{
private readonly RequestDelegate _next;
public CorsMiddleWare(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "http://172.16.1.35:3000");
return _next(httpContext);
}
}
public static class CorsMiddlewareExtensions
{
public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CorsMiddleWare>();
}
}
请问有人有想法吗?
控制台中的返回标题如下
EDIT : Return headers in console is as below
请求网址: http://172.16.1.34:1980/api/accounts/uploadAvatar 推荐人政策:降级时不推荐人日期:2020年4月14日,星期二03:50:49 GMT服务器:Microsoft-IIS/10.0传输编码:分块X-Powered-By:ASP.NET接受:application/json,text/plain,/接受编码:gzip,压缩接受语言:en-US,en; q = 0.9授权:承载eyJhb .....连接:keep-alive内容长度:22869内容类型:application/json; charset = UTF-8主机:172.16.1.34:1980来源: http://172.16.1.35:3000 推荐人: http://172.16.1.35:3000/create-profile 用户代理:Mozilla/5.0(Windows NT 10.0; Win64; x64)AppleWebKit/537.36(KHTML,如Gecko)Chrome/80.0.3987.163 Safari/537.36 {fileName:头像",mediaType:"image/png",…} fileName:头像" mediaType:"image/png"缓冲区:"iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAYAAACI7Fo9AAAgAE
Request URL: http://172.16.1.34:1980/api/accounts/uploadAvatar Referrer Policy: no-referrer-when-downgrade Date: Tue, 14 Apr 2020 03:50:49 GMT Server: Microsoft-IIS/10.0 Transfer-Encoding: chunked X-Powered-By: ASP.NET Accept: application/json, text/plain, / Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Authorization: Bearer eyJhb..... Connection: keep-alive Content-Length: 22869 Content-Type: application/json;charset=UTF-8 Host: 172.16.1.34:1980 Origin: http://172.16.1.35:3000 Referer: http://172.16.1.35:3000/create-profile User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 {fileName: "avatar", mediaType: "image/png",…} fileName: "avatar" mediaType: "image/png" buffer: "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAYAAACI7Fo9AAAgAE
推荐答案
通过更改对象类型解决的问题是将图像文件发送到MultipartDataMediaFormatter.V2中包含的HttpFile中./iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter"rel =" nofollow noreferrer> https://github.com/iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter
The problem solved by changing the type of object is sending as image file to HttpFile contains in MultipartDataMediaFormatter.V2 https://github.com/iLexDev/ASP.NET-WebApi-MultipartDataMediaFormatter
上传视图模型:
public class ProfileAvatarUploadViewModel
{
public HttpFile Image { get; set; }
}
Api控制器:
[HttpPost("UploadAvatar")]
[Authorize(AuthenticationSchemes = "Bearer", Roles = "Manager,Admin,User")]
public async Task<IActionResult> UploadAvatar([FromBody] ProfileAvatarUploadViewModel model)
{
var userId = User.FindFirst(ClaimTypes.Name)?.Value;
if (userId == null || !await _userAccountRepository.IsExists(int.Parse(userId)))
{
return Forbid();
}
var avatarToUpload = new ProfileAvatarUploadModel
{
UserAccountId = int.Parse(userId),
UploadedImage = model.Image
};
var uploadedAvatar = await _profileAvatarRepository.UploadAvatar(avatarToUpload);
return Ok(uploadedAvatar);
}
存储库:
public async Task<ProfileAvatarViewModel> UploadAvatar(ProfileAvatarUploadModel model)
{
var (key, value) = SVCardTools.SaveImage(model.UploadedImage);
if (key.Equals(false))
{
throw new Exception(value);
}
var newAvatar = new ProfileAvatar
{
UserAccountId = model.UserAccountId,
AvatarUrl = value,
IsActive = false,
IsPublic = false
};
_context.Entry(newAvatar).State = EntityState.Added;
await _context.SaveChangesAsync();
return ProfileAvatarViewModel.Set(newAvatar);
}
SaveImage功能:
public static KeyValuePair<bool, string> SaveImage(HttpFile file)
{
var bytes = file.Buffer;
try
{
var fileExt = file.MediaType.Split('/')[1];
switch (fileExt.ToLower())
{
case "png":
fileExt = ".png";
break;
case "jpg":
fileExt = ".jpg";
break;
default:
return new KeyValuePair<bool, string>(false, "Message");
}
var sb = new StringBuilder();
sb.Append(DateTime.Now.Ticks);
var saveFilePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\avatars",
$"{sb}{fileExt}");
var saveDbPath = $"{sb}{fileExt}";
if (bytes.Length > 0)
{
using (var stream = new FileStream(saveFilePath, FileMode.Create))
{
stream.Write(bytes, 0, bytes.Length);
}
}
return new KeyValuePair<bool, string>(true, saveDbPath);
}
catch (Exception e)
{
var message = e.Message;
return new KeyValuePair<bool, string>(false, message);
}
}
这篇关于Asp.Net Core API CORS政策错误仅在文件上传中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!