Search code examples
apipostcorsaurelia

Aurelia Post with http-fetch-client producing an options request


I'm creating a small forum where people in our company can put up adverts for goods or services they want to sell on the fly, using aurelia. I have a list of adverts page working fine, a details page for each advert working fine both using get requests from an api. However i can't seem to get the work the Post reqeust when someone wants to add a comment on an advert.

@inject(HttpClient)
export class ApiData {
    constructor(httpClient) {
        httpClient.configure(config => {
            config
                .withBaseUrl("MyUrl");
        });
        this.http = httpClient;
        //.configure(x => {x.withHeader('Content-Type', 'application/json');});
    }

    postAdvertComment(comment, id) {
        return this.http.fetch(`/adverts/${id}/comments`, {
            method: "post",
            body: json(comment),
            headers: {
                'Accept': 'application/json'
            }
        });
    } 

    getAdverts() {
        return this.http.fetch("/adverts")
            .then(response => {
                return this.adverts = response.json();
            });
    }

    getAdvert(id) {
        return this.http.fetch(`/adverts/${id}`)
            .then(response => {
                return this.advert = response.json();
            });
    }
}

Doing this project we've had some issue with CORS, all solved by adding in AllowCors tags in the api, including all methods etc.

<add key="CorsAllowedOrigins" value="*" />
<add key="CorsAllowedHeaders" value="" />
<add key="CorsAllowedMethods" value="*" />

However when i try and run the post, its running an options method and returns a 400 Bad request. Here

We also get the following CORS error:

Fetch API cannot load MyURL/api/adverts/2/comments. 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:49877' is 
therefore not allowed access. The response had HTTP status code 400. If an 
opaque response serves your needs, set the request's mode to 'no-cors' to fetch 
the resource with CORS disabled.

I don't know if it's a problem with our c# api or with how I'm trying to post from aurelia, but we have tried sending requests from postman and it works fine, tried sending post request within the same app using jquery and it works fine, and all the get requests work fine, but for some reason this post is causing all sorts of problems.


Solution

  • It seems to be a problem in your WebAPI, but before giving you some possible solutions I'd like to show you some important things.

    • Postman is not affected by CORS, so all requests work.
    • jQuery ajax uses XHR (XmlHttpRequest object) while aurelia-fetch-client uses fetch (window.fetch. However, the fetch-polyfill uses XHR in the background). They are different approaches to solve the same problem. Just because one of them work, doesn't actually mean that the other one should work too.
    • The OPTIONS request is made by fetch, that's how it works. More information here https://developers.google.com/web/updates/2015/03/introduction-to-fetch?hl=en

    To solve this problem try to remove those tags from web.config, and allow CORS in your Startup.cs. Like this:

    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll); //or another parameter
        //rest of your code
    }
    

    You don't have to set the content-type header to application/json. It is automatically made when you use the json() function ---> body: json(comment)

    If you are using OWIN you might have to send the content-type as x-www-form-urlenconded. In that case, take a look at this Post 'x-www-form-urlencoded' content with aurelia-fetch-client