Web API和MVC 5控制器上的CORS:使用fetch和FormData上传图像



我有一个应用程序,它的前端和后端都在不同的.NET项目上运行。前端是运行在ASP.NET 5上的Aurelia web应用程序。此Aurelia应用程序(从现在起前端(从Web API 2/MVC 5应用程序(此后,后端

由于前端和后端是不同的应用程序,我为Web API和令牌承载请求的Start.Auth.cs设置了CORS。

FronEnd正在http://localhost:49850上运行。

现在,对于一些代码(这都在后端(

开始.Auth.cs

整个应用程序都位于登录表单后面,因此在Start.Auth.cs文件中,除了在static Startup()上设置基于令牌的身份验证之外,方法I还有一个中间件,它在还没有可用令牌的情况下向请求添加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);

正在上载文件

一切都很好;我可以对Web API执行GETPOST请求而不会出现问题,当尝试上传图像时会出现问题。

为了上传到文件,我在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控制器

这已经是The FrontEnd的一部分了。

要调用此方法,我使用Aurelia的Fetch客户端:

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

问题

如果我从WebApiConfig.cs中删除所有CORS设置,并且在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.

"有趣"的是,如果我尝试用REST控制台调用那个url,我不会得到404。

我已经尝试将[HttpOptions]属性添加到操作方法中;我尝试过按照这里和这里的描述创建ActionFilterAttributes,甚至在web.config中设置uip CORS,但都无济于事。

我知道问题是FileController是一个常规的MVC控制器,而不是Web API控制器,但它是否仍然可以让CORS工作?

你试过这个吗

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

在ApplicationOAuthProvider.cs文件中

最新更新