T. Szilard
T. Szilard

Reputation: 25

Why and how this simple node.js proxy works?

I have a frontend-only web application on Netlify which has to consume an API on OpenSubtitles.org. Although OpenSubtitles.org enables CORS, sometimes I got preflight errors, so I decided to use a proxy.

I had problems using Netlify's proxy feature, so I decided I will create my own proxy on Heroku, and send my requests from the frontend to there, so these will be proxied to OpenSubtitles.org from a server.

I came up with the following based on the code I found here:

const express = require('express');
const request = require('request');

express()
    .use('/', function(req, res) {
        req.pipe(
            request({
                url: 'http://rest.opensubtitles.org/search' + req.url,
                headers: {
                    'User-Agent': 'TemporaryUserAgent'
                }
            })
        ).pipe(res);
    })
    .listen(process.env.PORT || 8000);

I thought I deploy this, try it out, then I will enable CORS on it after that. However I've just realized it is working perfectly without doing anything else. How is it possible? Why can I call this from a frontend-only app on a different domain without explicitly enabling CORS?

Also, what if the server crashes, how to handle the errors there?

Upvotes: 2

Views: 1022

Answers (1)

peteb
peteb

Reputation: 19418

CORS is working because the url you're requesting responds with the header Access-Control-Allow-Origin set with a value of *. Since you're piping that response and its headers back to the original res object, it will enable CORS as if it was coming from your local proxy.

Below is a more straightforward example of how to proxy a request to another site and return its response intact using node streams.

const express = require('express')
const request = require('request')
const port = process.env.PORT || 1337

let server = express()

const proxyMiddleware = (req, res, next) => {
  let url = `https://www.google.com/${req.url}`
  let proxyRequest = request(url)

  // Pass request to proxied request url
  req.pipe(proxyRequest)

  // Respond to the original request with the response from proxyRequest
  proxyRequest.pipe(res)
}

server.use(proxyMiddleware)

server.listen(port, () => console.log(`Listening on ${port}`))

Upvotes: 1

Related Questions