Home nodejs proxy local api calls to external rest api service (no express.js)
Reply: 0

nodejs proxy local api calls to external rest api service (no express.js)

user46661
1#
user46661 Published in September 19, 2018, 6:47 pm

I'm running the demo app of angularjs (angular-seed) using nodejs with the default project file /scripts/web-server.js (see below)

I would like node js to proxy/redirect all the local calls to /api to the external Rest api endpoint http://www.mywebsite.com/api in order to avoid the cross domain origin policy.

How should I edit the web-server.js below to achieve the proxy redirect?

All the example I found do use express.js. I'm using node.js only as development environment so I've no interest in using express.js.

Default web-server.js nodejs script:

#!/usr/bin/env node

var util = require('util'),
    http = require('http'),
    fs = require('fs'),
    url = require('url'),
    events = require('events'),
    request = require('request');
    ;

var DEFAULT_PORT = 8000;

function main(argv) {
  new HttpServer({
    'GET': createServlet(StaticServlet),
    'HEAD': createServlet(StaticServlet)
  }).start(Number(argv[2]) || DEFAULT_PORT);
}

function escapeHtml(value) {
  return value.toString().
    replace('', '>').
    replace('"', '"');
}

function createServlet(Class) {
  var servlet = new Class();
  return servlet.handleRequest.bind(servlet);
}

/**
 * An Http server implementation that uses a map of methods to decide
 * action routing.
 *
 * @param {Object} Map of method => Handler function
 */
function HttpServer(handlers) {
  this.handlers = handlers;
  this.server = http.createServer(this.handleRequest_.bind(this));
}

HttpServer.prototype.start = function(port) {
  this.port = port;
  this.server.listen(port);
  util.puts('Http Server running at http://localhost:' + port + '/');
};

HttpServer.prototype.parseUrl_ = function(urlString) {
  var parsed = url.parse(urlString);
  parsed.pathname = url.resolve('/', parsed.pathname);
  return url.parse(url.format(parsed), true);
};

HttpServer.prototype.handleRequest_ = function(req, res) {
  var logEntry = req.method + ' ' + req.url;
  if (req.headers['user-agent']) {
    logEntry += ' ' + req.headers['user-agent'];
  }
  util.puts(logEntry);
  req.url = this.parseUrl_(req.url);
  var handler = this.handlers[req.method];
  if (!handler) {
    res.writeHead(501);
    res.end();
  } else {
    handler.call(this, req, res);
  }
};

/**
 * Handles static content.
 */
function StaticServlet() {}

StaticServlet.MimeMap = {
  'txt': 'text/plain',
  'html': 'text/html',
  'css': 'text/css',
  'xml': 'application/xml',
  'json': 'application/json',
  'js': 'application/javascript',
  'jpg': 'image/jpeg',
  'jpeg': 'image/jpeg',
  'gif': 'image/gif',
  'png': 'image/png',
  'svg': 'image/svg+xml'
};

StaticServlet.prototype.handleRequest = function(req, res) {
  var self = this;
  var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
    return String.fromCharCode(parseInt(hex, 16));
  });
  var parts = path.split('/');
  if (parts[parts.length-1].charAt(0) === '.')
    return self.sendForbidden_(req, res, path);
  fs.stat(path, function(err, stat) {
    if (err)
      return self.sendMissing_(req, res, path);
    if (stat.isDirectory())
      return self.sendDirectory_(req, res, path);
    return self.sendFile_(req, res, path);
  });
}

StaticServlet.prototype.sendError_ = function(req, res, error) {
  res.writeHead(500, {
      'Content-Type': 'text/html'
  });
  res.write('\n');
  res.write('Internal Server Error\n');
  res.write('

Internal Server Error

'); res.write('
' + escapeHtml(util.inspect(error)) + '
'); util.puts('500 Internal Server Error'); util.puts(util.inspect(error)); }; StaticServlet.prototype.sendMissing_ = function(req, res, path) { path = path.substring(1); res.writeHead(404, { 'Content-Type': 'text/html' }); res.write('\n'); res.write('404 Not Found\n'); res.write('

Not Found

'); res.write( '

The requested URL ' + escapeHtml(path) + ' was not found on this server.

' ); res.end(); util.puts('404 Not Found: ' + path); }; StaticServlet.prototype.sendForbidden_ = function(req, res, path) { path = path.substring(1); res.writeHead(403, { 'Content-Type': 'text/html' }); res.write('\n'); res.write('403 Forbidden\n'); res.write('

Forbidden

'); res.write( '

You do not have permission to access ' + escapeHtml(path) + ' on this server.

' ); res.end(); util.puts('403 Forbidden: ' + path); }; StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) { res.writeHead(301, { 'Content-Type': 'text/html', 'Location': redirectUrl }); res.write('\n'); res.write('301 Moved Permanently\n'); res.write('

Moved Permanently

'); res.write( '

The document has moved here.

' ); res.end(); util.puts('301 Moved Permanently: ' + redirectUrl); }; StaticServlet.prototype.sendFile_ = function(req, res, path) { var self = this; var file = fs.createReadStream(path); res.writeHead(200, { 'Content-Type': StaticServlet. MimeMap[path.split('.').pop()] || 'text/plain' }); if (req.method === 'HEAD') { res.end(); } else { file.on('data', res.write.bind(res)); file.on('close', function() { res.end(); }); file.on('error', function(error) { self.sendError_(req, res, error); }); } }; StaticServlet.prototype.sendDirectory_ = function(req, res, path) { var self = this; if (path.match(/[^\/]$/)) { req.url.pathname += '/'; var redirectUrl = url.format(url.parse(url.format(req.url))); return self.sendRedirect_(req, res, redirectUrl); } fs.readdir(path, function(err, files) { if (err) return self.sendError_(req, res, error); if (!files.length) return self.writeDirectoryIndex_(req, res, path, []); var remaining = files.length; files.forEach(function(fileName, index) { fs.stat(path + '/' + fileName, function(err, stat) { if (err) return self.sendError_(req, res, err); if (stat.isDirectory()) { files[index] = fileName + '/'; } if (!(--remaining)) return self.writeDirectoryIndex_(req, res, path, files); }); }); }); }; StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) { path = path.substring(1); res.writeHead(200, { 'Content-Type': 'text/html' }); if (req.method === 'HEAD') { res.end(); return; } res.write('\n'); res.write('' + escapeHtml(path) + '\n'); res.write('\n'); res.write(' ol { list-style-type: none; font-size: 1.2em; }\n'); res.write('\n'); res.write('

Directory: ' + escapeHtml(path) + '

'); res.write('
    '); files.forEach(function(fileName) { if (fileName.charAt(0) !== '.') { res.write('
  1. ' + escapeHtml(fileName) + '
  2. '); } }); res.write('
'); res.end(); }; // Must be last, main(process.argv);
share|improve this question

active oldest votes

Your Answer

StackExchange.ifUsing("editor", function () { StackExchange.using("externalEditor", function () { StackExchange.using("snippets", function () { StackExchange.snippets.init(); }); }); }, "code-snippets"); StackExchange.ready(function() { var channelOptions = { tags: "".split(" "), id: "1" }; initTagRenderer("".split(" "), "".split(" "), channelOptions); StackExchange.using("externalEditor", function() { // Have to fire editor after snippets, if snippets enabled if (StackExchange.settings.snippets.snippetsEnabled) { StackExchange.using("snippets", function() { createEditor(); }); } else { createEditor(); } }); function createEditor() { StackExchange.prepareEditor({ heartbeatType: 'answer', convertImagesToLinks: true, noModals: false, showLowRepImageUploadWarning: true, reputationToPostImages: 10, bindNavPrevention: true, postfix: "", onDemand: true, discardSelector: ".discard-answer" ,immediatelyShowMarkdownHelp:true }); } });
 
StackExchange.ready( function () { StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20635799%2fnodejs-proxy-local-api-calls-to-external-rest-api-service-no-express-js%23new-answer', 'question_page'); } );

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged node.js api angularjs proxy cross-domain or ask your own question.

StackExchange.ready(function(){$.get('/posts/20635799/ivc/f131');});
StackExchange.ready(function () { StackExchange.responsiveness.addSwitcher(); }) (function(i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function() { (i[r].q = i[r].q || []).push(arguments) }, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga'); StackExchange.ready(function () { StackExchange.ga.init({ sendTitles: true, tracker: window.ga, trackingCodes: [ 'UA-108242619-1' ] }); StackExchange.ga.setDimension('dimension2', '|node.js|api|angularjs|proxy|cross-domain|'); StackExchange.ga.setDimension('dimension3', 'Questions/Show'); StackExchange.ga.trackPageView(); }); /**/ var _qevents = _qevents || [], _comscore = _comscore || []; (function() { var ssl = 'https:' == document.location.protocol, s = document.getElementsByTagName('script')[0], qc = document.createElement('script'); qc.async = true; qc.src = (ssl ? 'https://secure' : 'http://edge') + '.quantserve.com/quant.js'; s.parentNode.insertBefore(qc, s); _qevents.push({ qacct: "p-c1rF4kxgLUzNc" }); /**/ var sc = document.createElement('script'); sc.async = true; sc.src = (ssl ? 'https://sb' : 'http://b') + '.scorecardresearch.com/beacon.js'; s.parentNode.insertBefore(sc, s); _comscore.push({ c1: "2", c2: "17440561" }); })();
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.339715 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO