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