Asp.Net Core API CORS政策错误仅在文件上传中 [英] Asp.Net Core API CORS policy error only in file upload

查看:63
本文介绍了Asp.Net Core API CORS政策错误仅在文件上传中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仅当使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆