Our Blog

Let us find tech solutions together

May 01

React to CORS with an Express Proxy

By Andrew Lombardi | Comments

 

If you’re building any application using web technology destined for a browser it will likely need to interact with a third party API. Web development has taken a lot of the wonderful patterns from backend development we’ve all enjoyed and moved it to the frontend. With a server-based backend we would be looking at access to a persistence infrastructure possibly directly (though that isn’t the best practice), or through a first-party API with a pattern of controls based on REST or GraphQL. With front-end JavaScript frameworks in order to move beyond mostly a toy, you’ll be accessing data through a first-party or a third-party API.

Third party APIs are application programming interfaces provided by third parties with systems outside of your immediate control like Twitter, Google or Amazon. They allow you to access a curated set of functionality via typically REST or GraphQL or similar. They allow for retrieving applicable data or mutating state stored in these systems.

The difference between a first-party API and a third-party API is one of origin, the same origin identifies access controls which let you access anything at the same host origin. As long as you are sticking with first-party APIs you will never have any further issues. For a lot of applications, this works wonderfully.

The Joy of 3rd party APIs

CORS. Until you’ve had to talk with a third-party API you may have been unaware of this wonderful beast. Today is the day, and a simple NodeJS proxy might be the way. First we probably need to quickly define what it is.

Cross-origin resource sharing

Cross-origin resource sharing is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos.

So if you’re looking for access using a library like Axios or Fetch and using the same host, no problem. If however you’re trying to access let’s say, a user’s geo location using their IP

hey ho

let’s go

Pre-flight Requests

Discuss pre-flight requests, the OPTIONS header that gets passed

Browser-based Options

If you’re testing locally…

Firefox

Firefox has a great plugin / extension system and the best way to disable CORS for when you’re testing your web application locally is to use CORS Everywhere. During normal / regular browsing you should strive to keep this off.

Google Chrome

The easiest way to disable the CORS restrictions is to install the plugin Allow CORS: Access-Control-Allow-Origin. Make sure to turn it off during regular browsing as it can cause some unforeseen issues.

Safari

No plugin necessary. Easiest way is to enable the developer menu from Preferences -> Advanced and under the Develop menu select Disable Cross-Origin Restrictions. Reload the page.

Build a NodeJS proxy server

Let’s build a proxy server which will let us pass the necessary headers

1
2
3
const express = require('express')
const request = require('request')
const cors = require('cors')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const app = express()

const corsOptions = {
    origin: (origin, callback) => {
        callback(null, true)
    },
}
app.options('*', cors(corsOptions))

const PRODUCTION_URL = 'https://virustrack.live'
const STAGING_URL = 'https://staging.virustrack.live'
const TEST_URL = 'https://test.virustrack.live'

const environment = process.env.NODE_ENVIRONMENT ? process.env.NODE_ENVIRONMENT : "production"


const url = environment === "production" ? PRODUCTION_URL : environment === "staging" ? STAGING_URL : TEST_URL

app.use('/', cors(corsOptions), (req, res) => {
    const request_url = `${url}${req.url}`

    req.pipe(request(request_url)).pipe(res)
});

app.listen(process.env.PORT || 3100)

Join the Mystic Team

If articles like this, and technology that we discuss on the blog is interesting to you, let us know