m.tracey
m.tracey

Reputation: 333

CORS blocking post request even though CORS is enabled in configuration ASP.NET Core Web API

I'm trying to make a simple post request to my Web API, but I am getting a CORS error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:5001/expression/add. (Reason: header ‘content-type’ is not allowed according to header ‘Access-Control-Allow-Headers’ from CORS preflight response).

The request is as follows:

export async function sendPostRequest(request, object) {

    try {

        const response = await fetch(request, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(object),
        });

        const result = await response.json();

        return result;

    } catch (error) {
        console.error(error);
    }
}

And the url and object passed into this function is as follows:

var url = 'https://localhost:5001/expression/add';

var toSave = {
    'userId': 1,
    'expression': 'hello'
};

This is the endpoint:

[ApiController]
[Route("[controller]")]
public class ExpressionController : ControllerBase
{
    [HttpPost]
    [Route("add")]
    public void Save([FromBody] ExpressionDbo expression)
    {
        repository.SaveExpression(expression);
    }
}

My startup method:

public void ConfigureServices(IServiceCollection services)
{
    var connection = "Server=localhost;Database=xxxx;User Id=xxxx;Password=xxxx;";

    services.AddDbContext<EvaluateContext>(options => options.UseSqlServer(connection));

    services.AddScoped<IExpressionRepository, ExpressionRepository>();

    services.AddCors(options =>
    {
        options.AddPolicy(name: MyAllowSpecificOrigins,
                    builder =>
                    {
                        builder.WithOrigins("http://localhost:8080");

                    });
    });
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseCors(MyAllowSpecificOrigins);

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

GET requests work fine, and this same post request works fine in Postman, cannot seem to figure out where I have gone wrong.

Maybe I need to set the Access-Control-Allow-Headers header somewhere?

This question: Enabling CORS with WebAPI PUT / POST requests? did not help, neither did Cross-Origin Request Blocked: Occur even after CORS enabled on my API ; or my other searches.

Upvotes: 0

Views: 3791

Answers (1)

Dor Lugasi-Gal
Dor Lugasi-Gal

Reputation: 1572

To allow specific headers to be sent in a CORS request, called author request headers, call WithHeaders and specify the allowed headers:

options.AddPolicy("MyAllowHeadersPolicy",
    builder =>
    {
        // requires using Microsoft.Net.Http.Headers;
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

To allow all author request headers, call AllowAnyHeader:

options.AddPolicy("MyAllowAllHeadersPolicy",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
               .AllowAnyHeader();
    });

same thing with methods

 options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com")
                            .WithMethods("PUT", "DELETE", "GET");
                });

or

 options.AddPolicy(name: "MyPolicy",
                builder =>
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com")                                                  
                           .AllowAnyMethod();
                });

also, take note that

http://localhost:8080 
https://localhost:8080 
http://localhost:5001 

are not equal origins.

Upvotes: 5

Related Questions