2

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();
            });
    }
4

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();
    });  
  • 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 Dec 11 '18 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.) – Sergei Sergeev Dec 11 '18 at 10:40
  • Based on the link I provided, for POST you can't set json content-type – Sergei Sergeev Dec 11 '18 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 Dec 11 '18 at 10:59
  • That's absolutely normal. If Fetch API doesn't work for you, just use an alternative. – Sergei Sergeev Dec 11 '18 at 11:04

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

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