6

I'v been trying to access various apis through SPFx and I am constantly seeing this issue. I do not know how to fix this can anyone assist or explain what I am doing wrong or missing?

This works perfectly fine with $.getJSON("https://www.mindicador.cl/api").then(console.log)

workbench.html:1 Access to fetch at 'https://www.mindicador.cl/api' from origin 'https://localhost:4321' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

My function:

  private makeRequest(): Promise<HttpClientResponse> {
        const url = `https://www.mindicador.cl/api`;

        const requestHeaders: Headers = new Headers();

        requestHeaders.append("Content-type", "application/json");
        requestHeaders.append("Accept", "application/json");
        requestHeaders.append("Access-Control-Allow-Origin", "*");

        const httpClientOptions: IHttpClientOptions = {
            headers: requestHeaders,
            method: "GET"
        };

        return this.context.httpClient
            .get(url, HttpClient.configurations.v1, httpClientOptions)
            .then(response => {
                console.log(response);
                return response.json();
            });
    }
1

1 Answer 1

9

The difference between jquery call and the native httclient call is a method of making http asynchronous request.
jquery uses old good xhr, but httpclient uses modern fetch api. When making CORS request with fetch API sometimes browser sends preflight request to understand server CORS possibilities (which origins are accepted, which headers, etc.). Your service, https://www.mindicador.cl/api doesn't support preflight requests, that's the reason why it fails.

The good news is that it's possible to remove preflight request under certain conditions. You can read more in this answer here:

To disable the OPTIONS request, below conditions must be satisfied for ajax request: Request does not set custom HTTP headers like 'application/xml' or 'application/json' etc The request method has to be one of GET, HEAD or POST. If POST, content type should be one of application/x-www-form-urlencoded, multipart/form-data, or text/plain

Which means that you should remove all custom headers to make it work:

const url = `https://www.mindicador.cl/api`;

const httpClientOptions: IHttpClientOptions = {
    headers: new Headers(),
    method: "GET",
    mode: "cors"
};

this.context.httpClient
    .get(url, HttpClient.configurations.v1, httpClientOptions)
    .then(response => {
        console.log(response);
        return response.json();
    });  
6
  • Hey Sergei, this helped. The solution was to remove the headers. However, I can't make post requests to this api (api.slack.com/changelog/2017-10-keeping-up-with-the-jsons) and the instructions directly state I need to pass in certain headers in order for JSON to be read by the API using fetch. I've used Axios (XHR) and it works for my POST requests but I can't use the SPFx HttpClient to accomplish the same thing.
    – Batman
    Commented Dec 11, 2018 at 10:01
  • That's all because SPFx uses Fetch API, which sometimes requires preflight (OPTIONS) request prior actual http call. I think the only option for you is to go ahead with xhr (axios, jquery, etc.) Commented Dec 11, 2018 at 10:40
  • Based on the link I provided, for POST you can't set json content-type Commented Dec 11, 2018 at 10:43
  • Oh okay. Is this normal? I would think that SPFx webparts would be a great opportunity to create elements that access 3rd party APIs, which I wouldn't consider out of the norm for SharePoint sites, but it seems very challenging to achieve this. Most examples I see are related to Graph, Azure or SP calls but nothing with 3rd parties.
    – Batman
    Commented Dec 11, 2018 at 10:59
  • That's absolutely normal. If Fetch API doesn't work for you, just use an alternative. Commented Dec 11, 2018 at 11:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.