0

I am trying to make api call through Redux actions & reducers in my React Application.

However, I am getting this CORS issue on my browser.

I was wondering if i can resolve this issue from a client side as i donot have any access to the API internally.

Could anyone please help me solve this issue?

Here is the code for newsActions.js :

import * as types from './actionTypes';

const API_KEY = "<Redacted>";

export const getNewsApi = () => {
  debugger;
  return (dispatch, getState) => {
    dispatch({
      type: 'API_REQUEST',
      options: {
        method: 'GET',
        service: 'news',
        mode: 'cors',
     headers:{
         'Access-Control-Allow-Origin':'*'
     },
        endpoint: `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=${API_KEY}`,
        actionTypes: {
          success: types.GET_NEWS_API_SUCCESS,
          error: types.GET_NEWS_API_ERROR
        }
      }
    });
  }
}

Here is the code for server.js :

var express = require('express');
var app = express();

var cors = require('cors');

let __homeglobals = [];

app.use(cors());
app.set("jsonp callback", true);


var server = app.listen(8082, function () {
   var host = server.address().address;
   var port = server.address().port;
   
   console.log("Example app listening at http://%s:%s", host, port);
});

If you need additional info or have questions, please comment them below.

Thank you.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Eunicorn
  • 601
  • 6
  • 16
  • 29

2 Answers2

2

You can solve the Cross Origin issue by proxying from your origin (the web server) to the API server.

Change the calls in the client code to send requests to /api/whatever (deliberate lack of scheme, host and port there, so it uses the one that served the page). From the client's perspective this is no longer a request to a different host.

I guess that in the action you dispatch, this would correspond to changing the endpoint property:

endpoint: `/api/top-headlines?country=us&category=business&apiKey=${API_KEY}`

Then set up a path-based proxy in your web server to match routes starting with /api and proxy them to https://newsapi.org/v2. For example, using http-proxy-middleware:

var proxy = require('http-proxy-middleware');

app.use('/api', proxy({target: 'https://newsapi.org/v2'}));

Note that the "Access-Control-Allow-Origin" header is set by the server, not the client, so it's not doing anything useful in your example.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • Thank you for your answer! How do I "change the calls in the client code to send requests to ```/api/whatever```"? Which file do I add that? – Eunicorn May 10 '18 at 20:12
  • I don't know how the action you dispatch translates into an AJAX request but I guess you just change `endpoint` from `https://news...` to `/api/...`. – Tom Fenech May 10 '18 at 20:14
  • @Eunicorn I edited my answer to add the change to `endpoint` – Tom Fenech May 10 '18 at 20:28
1

I was wondering if i can resolve this issue from a client side as i donot have any access to the API internally.

Unfortunately you can't; the server behind the request has to set the correct CORS headers for CORS to work (you can't set it from the client-side request). This is enforced by the browser itself, and not something you can resolve from client-side code.

Quoting from MDN:

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request HTTP resources from the same domain the application was loaded from unless CORS headers are used.

In this case, it looks like the API is intended to be used from a server, not directly from a browser.

FeifanZ
  • 16,250
  • 7
  • 45
  • 84