2

This is my First React.js app and I am trying to make a simple api call to a non auth api. I am deploying the app in Heroku(Framework: React.js (create-react-app)) and its running Express Node.js and utilizing React Router. My problem is, upon a simple button click( calls handleClick() ) I want to make a API GET Request but I am constantly getting an error message via console

Fetch API cannot load https://rest-it-test.herokuapp.com/rest. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://myherokuapp.herokuapp.com' 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.

src/components/App

import React, { PropTypes, Component } from 'react';
import classnames from 'classnames';

import logo from './logo.svg';
import './style.css';

var Twitter = require('twitter');
var request = require('request');

var client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER,
  consumer_secret: process.env.TWITTER_SECRET
});



class App extends Component {
  // static propTypes = {}
  // static defaultProps = {}
  // state = {}
  constructor(props)
  {
    super(props)
    this.state = {
      input: ""
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  getInitialState(){
    return { input: '' };
  }

  handleChange(e) {
    this.setState({ input: e.target.value });
  }

  handleClick(){
    console.log(this.state.input);
    request('https://rest-it-test.herokuapp.com/rest', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body) // Print the google web page.
         }
    });

  }

  render() {
    const { className, ...props } = this.props;
    return (
      <div className={classnames('App', className)} {...props}>
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          <code>src/App.js</code> and save to reload.
        </p>
        <p>
          Testing HTML!!!
        </p>
        <input type="text" onChange={ this.handleChange } />
        <input
          type="button"
          value="Search"
          onClick={this.handleClick}
        />
      </div>
    );
  }
}

export default App;

server/app.js

const express = require('express');
const morgan = require('morgan');
const path = require('path');
var cors = require('cors');

const app = express();

app.use(cors());

// Setup logger
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));

// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));

// Use for React Router... Will always return main.
app.get('*', (req, res) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Headers", "Content-Type");
  res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
  res.sendFile(path.resolve(__dirname, '..', 'build', 'index.html'));
});


module.exports = app;

Here are a list of solutions I have tried:

  1. Used different library such as restler.
  2. Tried passing headers Access-Control-Allow-Origin", "*", Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"..etc on the request call itself.

There are no other solutions I can think of, if anyone has solved this please let me know.

Thanks!

1 Answers1

0

You're running into a couple of different issues.

First, CORS. Browsers are essentially sandboxed with respect to domain unless both the client request and remote server response contain the headers necessary to overcome this. The error message you quote is telling you that the response was blocked because the response did not contain any 'Access-Control-Allow-Origin' header. This is not something you can remedy by setting headers on your Express server; this is something that Twitter's API would have to set. To my knowledge, Twitter does not allow this so it's a dead end.

Second, check out that status code. If you could get past CORS issue, the response you would receive would be this:

{
  "errors": [
    {
      "code": 215,
      "message": "Bad Authentication data."
    }
  ]
}

In order to access the API, you're going to have to make your requests from your server (which will not have the CORS issue) and authenticate, probably via oauth flow.

Fissure King
  • 1,250
  • 7
  • 17
  • Thanks for your answer, but please look at #2 of my list. I tried a restful GET from something I know works and it does not require authentication. It doesn't matter if it's twitter I am making the GET from, it fails just making any simple GET request. – Felix Ramirez Jan 23 '17 at 07:41
  • Without seeing that request I can't do much but I can recommend trying it in postman and closely inspecting the response. – Fissure King Jan 23 '17 at 16:03