首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用express.js的代理

使用express.js的代理
EN

Stack Overflow用户
提问于 2012-05-04 00:20:45
回答 9查看 195.6K关注 0票数 195

为了避免同域AJAX问题,我希望我的node.js web服务器将来自URL /api/BLABLA的所有请求转发到另一个服务器,例如other_domain.com:3000/BLABLA,并透明地将此远程服务器返回的相同内容返回给用户。

所有其他URL(除/api/*外)都是直接服务的,没有代理。

如何使用node.js + express.js实现这一点?你能给出一个简单的代码示例吗?

( web服务器和远程3000服务器都在我的控制之下,都运行带有express.js的node.js )

到目前为止,我找到了这个https://github.com/http-party/node-http-proxy,但是阅读那里的文档并没有让我变得更明智。我最终得到了

var proxy = new httpProxy.RoutingProxy();
app.all("/api/*", function(req, res) {
    console.log("old request url " + req.url)
    req.url = '/' + req.url.split('/').slice(2).join('/'); // remove the '/api' part
    console.log("new request url " + req.url)
    proxy.proxyRequest(req, res, {
        host: "other_domain.com",
        port: 3000
    });
});

但没有任何东西返回到原始web服务器(或最终用户),所以没有运气。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2012-05-04 00:47:49

您希望使用http.request创建对远程应用程序接口的类似请求并返回其响应。

如下所示:

const http = require('http');
// or use import http from 'http';


/* your app config here */

app.post('/api/BLABLA', (oreq, ores) => {
  const options = {
    // host to forward to
    host: 'www.google.com',
    // port to forward to
    port: 80,
    // path to forward to
    path: '/api/BLABLA',
    // request method
    method: 'POST',
    // headers to send
    headers: oreq.headers,
  };

  const creq = http
    .request(options, pres => {
      // set encoding
      pres.setEncoding('utf8');

      // set http status code based on proxied response
      ores.writeHead(pres.statusCode);

      // wait for data
      pres.on('data', chunk => {
        ores.write(chunk);
      });

      pres.on('close', () => {
        // closed, let's end client request as well
        ores.end();
      });

      pres.on('end', () => {
        // finished, let's finish client request as well
        ores.end();
      });
    })
    .on('error', e => {
      // we got an error
      console.log(e.message);
      try {
        // attempt to set error message and http status
        ores.writeHead(500);
        ores.write(e.message);
      } catch (e) {
        // ignore
      }
      ores.end();
    });

  creq.end();
});

注意:我还没有真正尝试过上面的方法,所以它可能包含解析错误,希望这能给你一个提示,告诉你如何让它工作。

票数 64
EN

Stack Overflow用户

发布于 2015-09-24 16:40:35

我发现了一种更短、更直接的解决方案,它使用express-http-proxy无缝地工作,并且还可以进行身份验证

const url = require('url');
const proxy = require('express-http-proxy');

// New hostname+path as specified by question:
const apiProxy = proxy('other_domain.com:3000/BLABLA', {
    proxyReqPathResolver: req => url.parse(req.baseUrl).path
});

然后简单地说:

app.use('/api/*', apiProxy);

注意:正如@MaxPRafferty所提到的,使用req.originalUrl代替baseUrl来保留查询字符串:

    forwardPath: req => url.parse(req.baseUrl).path

更新:正如Andrew提到的(谢谢!),有一个现成的解决方案使用了相同的原则:

npm i --save http-proxy-middleware

然后:

const proxy = require('http-proxy-middleware')
var apiProxy = proxy('/api', {target: 'http://www.example.org/api'});
app.use(apiProxy)

文档:http-proxy-middleware on Github

我知道我来晚了,但我希望这能帮助到一些人。

票数 109
EN

Stack Overflow用户

发布于 2014-03-11 21:01:00

要将trigoman的回答(完全归功于他)扩展到与POST一起工作(也可以与PUT等一起工作):

app.use('/api', function(req, res) {
  var url = 'YOUR_API_BASE_URL'+ req.url;
  var r = null;
  if(req.method === 'POST') {
     r = request.post({uri: url, json: req.body});
  } else {
     r = request(url);
  }

  req.pipe(r).pipe(res);
});
票数 50
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10435407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档