Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@peter
Last active August 24, 2020 12:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peter/6cc6596f3b73956035e58047716e6226 to your computer and use it in GitHub Desktop.
Save peter/6cc6596f3b73956035e58047716e6226 to your computer and use it in GitHub Desktop.
Local Node http proxy with CORS headers
// The use case is that you are developing a web app locally that makes Ajax requests to some external
// API that doesn't have sufficiently permissive CORS headers so your requests fail. The solution is to point the app
// to this local proxy which will allow CORS.
const http = require('http')
const axios = require('axios')
const HOSTNAME = '127.0.0.1'
const PROXY_BASE_URL = process.env.PROXY_BASE_URL;
const PORT = process.env.PORT || 9999
function addCorsHeaders(res) {
const headers = {
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE,OPTION',
'Access-Control-Allow-Origin': '*',
}
Object.keys(headers).forEach((header) => {
res.setHeader(header, headers[header])
})
}
function proxyRequestHeaders(headers) {
const OMIT_HEADERS = ['host']
return Object.entries(headers).reduce((acc, [key, value]) => {
if (!OMIT_HEADERS.includes(key)) acc[key] = value
return acc
}, {})
}
function addProxyResponseHeaders(headers, res) {
for (const [key, value] of Object.entries(headers)) {
res.setHeader(key, value)
}
addCorsHeaders(res)
}
const server = http.createServer(async (req, res) => {
if (req.method === 'OPTIONS') {
addCorsHeaders(res)
res.end()
} else if (req.method === 'GET') {
console.log(`cors-proxy req.url=${req.url}`)
const url = `${PROXY_BASE_URL}${req.url}`
const headers = proxyRequestHeaders(req.headers)
const validateStatus = () => true // make axios not throw on non-2xx status
const transformResponse = (data) => data; // make axios not parse JSON body
try {
const response = await axios.request({ url, headers, validateStatus, transformResponse })
res.statusCode = response.status
addProxyResponseHeaders(response.headers, res)
res.end(response.data)
} catch (error) {
console.log('cors-proxy error', error)
res.statusCode = 500
res.end(toString(error))
}
} else {
res.statusCode = 400
const message = `cors-proxy: request method ${req.method} unsupported (url=${req.url})`
console.log(message)
res.end(message)
}
})
server.listen(PORT, HOSTNAME, () => {
console.log(`cors-proxy running at http://${HOSTNAME}:${PORT}/ with PROXY_BASE_URL=${process.env.PROXY_BASE_URL}`)
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment