Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Request Can't Access API Control due to CORS

I have an end-point which simply uploads profile pictures. Eventhough I have enabled CORS, frontend team keeps telling me that they cannot be able to reach that end-point due to below error:

zone.js:2990 Access to XMLHttpRequest at 'https://gogobioimages.testortami.com/api/Image/PostAccountPicture' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

They are developing on Angular. On the other hand, mobile team (developing on Xamarin) don't have any problem on reaching that end-point. Below is my breakdown of API controller.

[EnableCors(origins: "*", headers: "*", methods: "*")]
public class BaseController : ApiController
{
    //common methods used on every controller written here
}

And, here is the end-point which contains image upload method:

public class ImageController : BaseController
{
    [IdentityBasicAuthentication]
    [Authorize]
    public HttpResponseMessage PostAccountPicture()
    {
        //some code here
    }
}

First, these [Authorize] and [IdentityBasicAuthentication] headers were placed on the top of the ImageController, but I read that this situation could end up mixing request pipeline, so I moved them on the top of action (didn't solve the problem though).

I also have these customHeader lines on my web.config:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Credentials" value="true"/>
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, OPTIONS" />
  </customHeaders>
</httpProtocol>

And, my handlers are described as below:

<handlers>
  <remove name="WebDAV" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler" />-->
  <remove name="TRACEVerbHandler" />
  <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

At the beginning, I don't have name="OPTIONSVerbHandler". After I added it to web.config, mobile requests start to getting 500 Internal Server Error.

Below is my Global.asax, which I have editted as per other suggestions (Application_BeginRequest was not included at the beginning):

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
        GlobalConfiguration.Configuration.Formatters.Add(new FormMultipartEncodedMediaTypeFormatter());
    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.Flush();
        }
    }
}

Finally, my WebApiConfig class as per below:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

I have also asked my front-end mate to share her ajax request with me. Its like that:

  $("form").submit(function(evt){evt.preventDefault(); var formData = new FormData($(this)[0]); $.ajax({
url: 'https://<our subdomain name is here>/api/Image/PostAccountPicture',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
enctype: 'multipart/form-data',
processData: false,
headers: {'Authorization':'Basic ' + localStorage.getItem('currentUser')} ,
success: function (response) {
  alert(response);
}});return false;});

I have also enabled CORS in my previous projects, and it was enough to set [EnableCors("*","*","*")] on the controller classes and making config.EnableCors() on WebApiConfig.cs without all the other above shown adjustments like the ones on web.config file.

Now, I don't have any idea what keeps front-end to reach my end-point.

Thank you in advance!

like image 436
RaZzLe Avatar asked Jul 29 '26 05:07

RaZzLe


1 Answers

I had the same issue on my side when developing with angular and using a local server between my browser and the backend (in order to update the gui on the fly when code change). We solved the issue by just adding the Allow CORS Plugin Chrome (and I suppose other browsers) dislike when the server handling the paages is not the same as the server where api calls are sent.

This of course is no issue in production as the browser is reaching the expected server and not a kind of man in the middle server.

like image 147
Bruno Belmondo Avatar answered Jul 30 '26 17:07

Bruno Belmondo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!