使用Expressjs作为跨域ajax调用的代理

时间:2013-01-16 10:55:27

标签: javascript ajax node.js cross-domain express

我正在开发一个完全基于外部API的网站。我没有任何服务器端逻辑。所有数据都将从外部API获取。后端服务器主要用于资产管理和路由。已经决定让nodejsexpressjs一起在后端运行。我想知道在expressjs路由中需要做哪些修改来路由(作为代理)所有跨域ajax API调用从浏览器到相应的站点并将json数据路由回浏览器?

1 个答案:

答案 0 :(得分:3)

我写了一个小代理来路由调用API,但我最终放弃了它,所以这可能需要更多的工作。基本思路是:

  • Ajax无法在每个浏览器中发出跨域请求
  • 您有http://api.example.com/
  • 的外部API
  • 您的应用程序位于http://foo.com/
  • 您希望代理http://foo.com/api/*http://api.example.com/*
  • 的所有内容

最好的方法是使用Streams。您希望过滤对foo.com/api/的所有请求,然后根据收到的网址向api.example.com发出请求。然后你将有4个对象:

  • foo.com
  • 发出的请求
  • 该请求的响应对象
  • api.example.com
  • 发出的请求
  • 来自API服务器的响应

所有这些都是Streams。第一个和最后一个是可读流,其他是可写流。所以你要做的就是将来自可读流的任何内容写入可写流。您可以使用可读流的pipe方法执行此操作。这看起来像:

requestFromBrowser.pipe(requestToAPI(function (responseFromAPI) {
  responseFromAPI.pipe(responseToBrowser);
}));

您仍然需要手动编写标题并可能处理其他详细信息。这就是我的基本代码。它是Connect / Express的中间件。

var http = require('http');

exports.proxy = function (prefix) {
  return function (req, res, next) {
    var options = {
      port: 3000,
      // the server receives a url like http://foo.com/api/(*)
      // send the proxy only (*)
      path: req.url.substr(prefix.length),
      // headers and the method need to be written explicitely
      method: req.method,
      headers: req.headers
    };
    if (req.url.indexOf(prefix) === 0) {
      req.pipe(http.request(options, function (proxy) {
        res.writeHead(proxy.statusCode, proxy.headers);
        proxy.pipe(res);
      }).on('error', next));
    } else {
      next();
    }
  };
};

我建议您寻找已经完成此操作的模块。 NPM注册表中可能不止一个。另外,请阅读有关Streams的更多信息,因为它们非常适合编写代理等。