DEV Community 👩‍💻👨‍💻

Cover image for Write your own CORS Proxy with NodeJS in no time.
decker
decker

Posted on

Write your own CORS Proxy with NodeJS in no time.

You know CORS otherwise you would not read this article, I guess. So let's get beyond it and straight to the solution coded in a few lines of JavaScript. Or better before, show the problem.

My demo page below shows it.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <textarea id="output" rows="20" cols="120"></textarea>

  <script type="module">
    const outputNode = document.getElementById('output')
    const TARGET_URL = 'https://datahub.erde-und-umwelt.de/en/api/getServiceConfiguration/climateResilience'
    const URL = TARGET_URL
    // const URL = `http://localhost:8088/${TARGET_URL}`
    fetch(URL)
      .then((response) => response.json())
      .then((data) => outputNode.textContent = JSON.stringify(data, null, 2))
      .catch((exception) => {
        outputNode.textContent = exception
      })
  </script>
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

It simply tries to request some JSON data from a REST API and puts the result into a textarea.

But this does not happen, because of the wrong CORS header - the request is not allowed for every client.

So it only shows an error.

To get beyond this, you can write a backend that requests the data for you and put it through with a universal CORS header, so everyone can use it.

I will write this backend in NodeJS means JavaScript. The idea is, as also visible in the page, putting a proxy in front of the requested URL like this:

http://localhost:8088/${TARGET_URL}
Enter fullscreen mode Exit fullscreen mode

That means a request to http://example.de is prefixed with http://localhost:8080 in result gives http://localhost:8080/http://example.de

The proxy receives the request and extracts the requested URL from the request and requests the data.

The code is pretty simple using the http-proxy-middleware.
There is not much to do, at all, as you can see below.

const express = require('express')
const cors = require('cors')
const { createProxyMiddleware } = require('http-proxy-middleware')

const app = express()
app.use(cors())
app.use(createProxyMiddleware({
  router: (req) => new URL(req.path.substring(1)),
  pathRewrite: (path, req) => (new URL(req.path.substring(1))).pathname,
  changeOrigin: true,
  logger: console
}))

app.listen(8088, () => {
  console.info('proxy server is running on port 8088')
})

Enter fullscreen mode Exit fullscreen mode

I therefore use the external NodeJS modules express, http-proxy-middleware and cors.

How is it done?

This creates the server.

const app = express()

Enter fullscreen mode Exit fullscreen mode

This enables CORS for all routes, methods and clients.

app.use(cors())

Enter fullscreen mode Exit fullscreen mode

The only special tricky line is this.

app.use(createProxyMiddleware({
  router: (req) => new URL(req.path.substring(1)),
  pathRewrite: (path, req) => (new URL(req.path.substring(1))).pathname,
  changeOrigin: true,
  logger: console
}))
Enter fullscreen mode Exit fullscreen mode

It creates the middleware. The middleware routes to the embedded URL and rewrites the path.

And that's it. You created a CORS Proxy in NodeJS.

Top comments (0)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post