Asp. Net Ошибка политики Core API CORS только при загрузке файла - PullRequest
0 голосов
/ 13 апреля 2020

У меня ошибка блокировки политики CORS только при загрузке файла на сервер с использованием As pNet Core API 3.1. Добавление политики cors к запуску различными способами и использование собственного промежуточного программного обеспечения не решило мою проблему.

Запуск:

// ConfigureServices

    services.AddCors(options =>
    {
        options.AddPolicy("EnableSVCCors", builder =>
        {
            builder
                .AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod()
                .Build();
        });
    });

// Настройка

    app.UseCors("EnableSVCCors");

Все методы API работают нормально при вызове с веб-сайта реагирующего клиента, но при попытке загрузить изображение появляется следующая ошибка:

Доступ к XMLHttpRequest по адресу http://172.16.1.34: 1980 / api / account / uploadAvatar 'from origin' http://172.16.1.35: 3000 'заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Я также пытаюсь изменить политику Cors, как показано ниже, но не работает:

    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 / account / uploadAvatar Использование PostMan и отправка строки base64 в качестве изображения работает нормально! Таким образом, нет проблем с ограничениями доступа к папке, в которой будет сохранено изображение.

Я также попытался добавить пользовательское промежуточное ПО, как показано ниже, но пока не работает:

    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>();
    }
}

У любого есть Любая идея, пожалуйста?

РЕДАКТИРОВАТЬ: Вернуться заголовки в консоли, как показано ниже

Запрос URL: http://172.16.1.34: 1980 / api / account / uploadAvatar Политика реферера: no-referer-when-downgrade Дата: вторник, 14 апреля 2020 г. 03:50:49 GMT Сервер: Microsoft-IIS / 10.0 Кодирование передачи: chunked X-Powered-By: ASP. NET Accept: application / json, текст / обычный текст, / Accept-Encoding: gzip, deflate Accept-Language: en-US, en; q = 0,9 Авторизация: Bearer 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 (K HTML, как Gecko) Chrome / 80.0.3987.163 Safari / 537.36 {fileName: "avatar", mediaType: "image / png",…} fileName: "avatar" mediaType: "image / png" буфер: "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAYAAACI7Fo9AAAgAE

1 Ответ

0 голосов
/ 14 апреля 2020

Проблема, решаемая путем изменения типа объекта, отправляется как файл изображения в HttpFile, содержащийся в 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);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...