Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS issue with Twitter api calls in Webpack dev server

I'm running into an issue getting responses from the twitter api (using npm package Twitter). In Chrome I am getting:

Failed to load https://api.twitter.com/1.1/search/tweets.json?q=node.js: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' 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.

So I enable CORS with a plugin and the error changes to:

Failed to load https://api.twitter.com/1.1/search/tweets.json?q=node.js: Response for preflight has invalid HTTP status code 400.

I'm not sure what to do at this point. I have tried a couple different things in my webpack.config.js:

var path = require('path');
var webpack = require('webpack');
var Dotenv = require('dotenv-webpack');

module.exports = {
    devServer: {
        inline: true,
        historyApiFallback: true,
        contentBase: './src',
        port: 3000,
        headers: {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
            "Access-Control-Allow-Credentials": "true",
            "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS"
        },
        proxy: {
            "/api": "http://localhost:3000"
        }
    },
    devtool: 'cheap-module-eval-source-map',
    entry: './dev/js/index.js',
    module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['babel'],
                exclude: /node_modules/
            },
            {
                test: /\.scss/,
                loader: 'style-loader!css-loader!sass-loader'
            },
            {
                loader: 'json-loader',
                test: /\.json$/ 
            }
        ]
    },
    output: {
        path: 'src',
        filename: 'js/bundle.min.js'
    },
    node: {
        console: false,
        fs: 'empty',
        net: 'empty',
        tls: 'empty'
    },
    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new Dotenv({
            path: './.env',
            safe: false
        })
    ]
};

This is the call I'm trying to make

import Twitter from 'twitter';

const client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER_KEY,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
  bearer_token: process.env.TWITTER_BEARER_TOKEN
});

client.get('search/tweets', {q: 'node.js'}, function(error, tweets, response) {
   console.log(tweets);
});

I tried it in firefox as well with a CORS plugin enabled and I get this error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.twitter.com/1.1/search/tweets.json?q=node.js. (Reason: CORS preflight channel did not succeed).

like image 508
Gerald Wangley Avatar asked Oct 15 '25 03:10

Gerald Wangley


2 Answers

I can think only of a workaround:

  • Use the chrome extension Allow-Control-Allow-Origin
  • Use proxy: instead of accessing https://api.twitter.com/1.1/search/tweets.json?q=node.js, use a proxy like https://cors-anywhere.herokuapp.com/ as a prefix: https://cors-anywhere.herokuapp.com/https://api.twitter.com/1.1/search/tweets.json?q=node.js
like image 147
Yossi Avatar answered Oct 17 '25 18:10

Yossi


I was doing it on react. I had the same problem, and what I did to get around that was to mount an express server in node, make test end point, require twitter and follow the steps on the npm site. Then I would hit the express end point with a fetch request on the front end, which in turn would gather data from twitter, and then would send the response from twitter back to the front end.

I ran the express server on localhost:4000 and my create-react-app on localhost:3000, and I went to package.json to add "proxy": "http://localhost:4000" above "scripts" : {} (doesn't really matter where though).

Worked like a charm ^_^

like image 20
ChronicLogic Avatar answered Oct 17 '25 19:10

ChronicLogic