Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling CORS when calling 3rd party API

yes this is a very famous question , I have tried many ways mentioned in the previous stack-overflow QnA, but nothing worked. I am trying to use BANZAI-Cloud API in my application , but it gives the following error enter image description here

here is my code of the service class

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs';
import { HttpHeaders } from '@angular/common/http';

@Injectable({providedIn:"root"})
export class PriceTableService{
   
    private priceurl = "https://banzaicloud.com/cloudinfo/api/v1/providers/google/services/compute/regions/asia-east2/products"
    // private priceurl = "https://jsonplaceholder.typicode.com/posts"
    
    constructor(private http:HttpClient){}
    httpOptions = {
        headers: new HttpHeaders({
            'Access-Control-Allow-Methods':'DELETE, POST, GET, OPTIONS',
            'Access-Control-Allow-Headers':'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With',
            'Content-Type':  'application/json',
            'Access-Control-Allow-Origin':'http://localhost:4200'
        })
      };
    getPrices(){
            this.http.get(this.priceurl,this.httpOptions).subscribe(result=>{
            console.log(result);
            return(result);
        })
     }
    ngOnInit() {
    }
}

this API works in the POSTMAN and CHROME but cannot get data into my angular application , when I replace the URL with any other fake API I can get data ,but the above mentioned API is not giving data ,If anyone can help me to clear this problem it would be a great help.

like image 611
Janith Udara Avatar asked Sep 26 '19 18:09

Janith Udara


People also ask

How do you resolve CORS issues in REST API?

To resolve a CORS error from an API Gateway REST API or HTTP API, you must reconfigure the API to meet the CORS standard. For more information on configuring CORS for REST APIs, see Configuring CORS for a REST API resource. For HTTP APIs, see Configuring CORS for an HTTP API.

Does CORS apply to APIs?

CORS is only a matter of Browsers, so if users visit site (example.com) and that site call the api in another domain (apidomain.com) using a browser you must set CORS. If you dont want to set * (any domain can connect), you should set CORS to allow only some domains.

Is CORS required for REST API?

Cross-origin resource sharing (CORS) is a browser security feature that restricts cross-origin HTTP requests that are initiated from scripts running in the browser. If your REST API's resources receive non-simple cross-origin HTTP requests, you need to enable CORS support.


Video Answer


2 Answers

First, you need to understand that the CORS check is done by the browser. It's a W3C specification. Any extensions or tools like Postman are not bound with that. That's the reason you got the result through Postman.

And the other thing is, you have tried to add Access-Control-Allow-Origin header to the request. That's not what CORS specification expects. You need to have the Access-Control-Allow-Origin header in the response. That means it needs to be added by the server-side.

Since you are calling a 3rd party API, I believe you don't have control over the server. Therefore asking to handle the CORS issue by setting up Access-Control-Allow-Origin will not be possible.

There are 3 ways you can resolve this problem assuming you don't have access to the server.

  1. By disabling CORS check in the browser(Not Recommended for Production).

  2. By using a CORS plugin in the browser(Not Recommended for Production).

  3. By requesting the resource through a proxy - The simplest way, what you can do is, write a small node server (or if you already have a back-end associate it with your front-end you can use it) which does the request for the 3rd party API and sends back the response. And in that server response now you can allow cross-origin header.

like image 56
Kanishka Madhuranga Avatar answered Oct 20 '22 15:10

Kanishka Madhuranga


As per this answer's 3rd way I have made a small node server with express and called BANZAICLOUD using the following code.

const express=require('express');
const request = require('request');
const app=express();

app.get('/data',(req,res,next)=>{
    request('https://banzaicloud.com/cloudinfo/api/v1/providers/google/services/compute/regions/asia-east2/products',
     function (error, response, body) {
         res.send(body)
    });  
});
const port =process.env.port || 3000;
app.listen(port,()=>{
    console.log(`From port ${port}`);
});

Then you can use the http://localhost:3000/data in the front end and get data.

like image 37
thilini wathsala Avatar answered Oct 20 '22 13:10

thilini wathsala