skip to Main Content

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).

3

Answers


  1. 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
    Login or Signup to reply.
  2. 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 ^_^

    Login or Signup to reply.
  3. Your browser sets an origin header when making the HTTP request to your webpack dev server proxy and the proxy forwards this origin header to Twitter. Most likely Twitter will reject the request based on its illegal origin. You can get around this by removing the origin header before the request is forwarded:

    devServer: {
      ...,
      proxy: {
        ...,
        onProxyReq: function onProxyReq(proxyReq, req, res) {
          proxyReq.removeHeader("origin")
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search