CORS на веб-API и MVC 5 Controller: загрузка изображений с помощью fetch и FormData

У меня есть приложение, которое имеет внешний и внутренний интерфейсы, работающие в разных проектах.NET. Внешний интерфейс - это веб-приложение Aurelia, работающее на ASP.NET 5. Это приложение Aurelia (с этого момента FrontEnd) получает все свои данные из приложения Web API 2/MVC 5 (далее - BackEnd).

Поскольку FrontEnd и BackEnd - это разные приложения, у меня есть настройка CORS, как для веб-API, так и для Start.Auth.cs для запроса токена на предъявителя.

FronEnd работает на http://localhost:49850,

Теперь для некоторого кода (это все в BackEnd)

Start.Auth.cs

Все приложение находится за формой входа в систему, поэтому внутри Start.Auth.cs файл, кроме настройки аутентификации на основе токена на static Startup(), метод у меня есть немного промежуточного программного обеспечения, которое добавляет Access-Control-Allow-Origin заголовок запроса в одном случае, когда токена еще нет: когда мы запрашиваем токен.

public void ConfigureAuth(IAppBuilder app)
{
    app.Use(async (context, next) =>
    {
        if (context.Request.Path.Value.Equals("/token"))
            context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:49850" });
        await next();
     });

     app.UseCors(CorsOptions.AllowAll);
     app.UseOAuthAuthorizationServer(OAuthOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

WebApiConfig.cs

Здесь я только что добавил EnableCorsAttribute так что это включить глобально.

var enableCors = new EnableCorsAttribute("http://localhost:49850", "*", "*");
config.EnableCors(enableCors);

Загрузка файлов

Все отлично работает; Я могу выполнить GET а также POST Запросы к веб-API без проблем, проблема возникает при попытке загрузки изображений.

Для загрузки в файлы у меня есть метод действия в контроллере ASP.NET MVC под названием FileControler,

FileController.cs

[HttpPost]
public ActionResult UploadImage(string id, string name = "")
{
    var files = (from string fileName in Request.File
                 select Request.Files[fileName]
                 into file
                 where file != null
                 select DoSomethingWithTheFile(file, id)).ToList();
    // ...

    return Json(arrayWithFileUrls);
}

Вызов контроллера MVC

Это уже часть FrontEnd.

Для вызова этого метода я использую Aurelia's Fetch Client:

upload(url, data, files) {
    let formData = new FormData();
    for (let key of Object.keys(data)) {
        formData.append(key, data[key]);
    }
    for (let i = 0; i < files.length; i++) {
        formData.append(`files[${i}]`, files[i]);
    }

    return this.http.fetch(url, {
        method: "POST",
        body: formData,
        headers: {
            cmsDatabase: sessionStorage["cmsDatabase"]
        }
    }).then(response => {
        return response.json();
    }).catch(error => {
        console.log(error);
    });
}

И вот звонок в upload метод выше:

// files comes from an <input type="file" />
upload("http://localhost:64441/file/uploadImage", { id: id }, files) 
     .then((uploadedPhotos) => {
          // do something with those file urls...
 }); 

Эта проблема

Все это работает, если я удаляю все настройки CORS из WebApiConfig.cs, И в Startup.Auth.cs Я заменяю вызов на промежуточное ПО app.UseCors(CorsOptions.AllowAll);, так что я знаю, что мой код в порядке, но как только я использую настройку CORS, описанную выше, все работает, кроме вызова http://localhost:64441/file/uploadImage, вернув даже 404:

Fetch API cannot load http://localhost:64441/file/uploadForSku. 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' 
header is present on the requested resource. 
Origin 'http://localhost:49850' is therefore not allowed access. 
The response had HTTP status code 404. If an opaque response serves your needs, 
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Самое смешное, что если я попытаюсь вызвать этот URL с помощью консоли REST, я не получу 404.

Я пытался добавить [HttpOptions] атрибут метода действия; Я пытался создать ActionFilterAttributes как описано здесь и здесь, и даже установка UIP CORS изнутри web.config, но безрезультатно.

Я знаю проблема в том что FileController является обычным контроллером MVC вместо контроллера Web API, но разве нельзя по-прежнему работать CORS?

1 ответ

Ты пробовал это

 context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

в файле ApplicationOAuthProvider.cs

Другие вопросы по тегам