express.js를 사용한 프록시 현명하지는 않았습니다. 나는 결국 var

동일한 도메인 AJAX 문제를 피하기 위해 node.js 웹 서버가 URL의 모든 요청 /api/BLABLA을 다른 서버 로 전달 other_domain.com:3000/BLABLA하고이 원격 서버가 투명하게 반환 한 것과 동일한 것을 사용자에게 반환하기를 원합니다 .

다른 모든 URL ( /api/*)은 프록시없이 직접 제공됩니다.

node.js + express.js로 어떻게 이것을 달성합니까? 간단한 코드 예제를 줄 수 있습니까?

(웹 서버와 원격 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
    });
});

그러나 원래 웹 서버 (또는 최종 사용자)에게 아무것도 반환되지 않으므로 운이 없습니다.



답변

http.request원격 API와 유사한 요청을 작성하고 응답을 리턴하는 데 사용하려고합니다 .

이 같은:

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();
});

주의 사항 : 나는 실제로 위의 시도를하지 않았으므로 구문 분석 오류가 포함될 수 있기를 바랍니다.이 작업을 수행하는 방법에 대한 힌트를 줄 것입니다.


답변

2020 년 2 월부터 요청 이 더 이상 사용되지 않습니다. 역사적인 이유로 아래 답변을 남겨 두겠습니다. 그러나이 문제에 나열된 대안으로 이동하시기 바랍니다 .

보관

비슷한 것을했지만 대신 요청을 사용했습니다.

var request = require('request');
app.get('/', function(req,res) {
  //modify the url in any way you want
  var newurl = 'http://google.com/';
  request(newurl).pipe(res);
});

나는 이것이 도움이되기를 바랍니다. 내가 이것을 할 수 있다는 것을 깨닫는 데 시간이 걸렸습니다. 🙂


답변

나는 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)

설명서 : Github의 http-proxy-middleware

나는이 파티에 늦었다는 것을 알고 있지만 이것이 누군가에게 도움이되기를 바랍니다.


답변

POST로 작업 하기 위해 trigoman 의 답변 (전체 크레딧) 을 확장하려면 (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);
});


답변

다음 설정을 사용하여 모든 것을 /rest백엔드 서버 (포트 8080)로 보내고 다른 모든 요청을 프론트 엔드 서버 (포트 3001의 웹팩 서버)로 보냅니다. 모든 HTTP 메소드를 지원하고 요청 메타 정보를 잃지 않으며 웹 소켓을 지원합니다 (핫 리로드에 필요함)

var express  = require('express');
var app      = express();
var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var backend = 'http://localhost:8080',
    frontend = 'http://localhost:3001';

app.all("/rest/*", function(req, res) {
  apiProxy.web(req, res, {target: backend});
});

app.all("/*", function(req, res) {
    apiProxy.web(req, res, {target: frontend});
});

var server = require('http').createServer(app);
server.on('upgrade', function (req, socket, head) {
  apiProxy.ws(req, socket, head, {target: frontend});
});
server.listen(3000);


답변

먼저 express 및 http-proxy-middleware를 설치하십시오.

npm install express http-proxy-middleware --save

그런 다음 server.js에서

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

const app = express();
app.use(express.static('client'));

// Add middleware for http proxying 
const apiProxy = proxy('/api', { target: 'http://localhost:8080' });
app.use('/api', apiProxy);

// Render your site
const renderIndex = (req, res) => {
  res.sendFile(path.resolve(__dirname, 'client/index.html'));
}
app.get('/*', renderIndex);

app.listen(3000, () => {
  console.log('Listening on: http://localhost:3000');
});

이 예에서는 포트 3000에서 사이트를 제공하지만 / api로 요청이 끝나면 localhost : 8080으로 리디렉션합니다.

http : // localhost : 3000 / api / login http : // localhost : 8080 / api / login으로 리디렉션


답변

다음은 require ( ‘request’) npm 모듈과 하드 코딩 된 프록시 대신 환경 변수를 사용하여 복사 준비가 된 답변입니다.

커피 스크립트

app.use (req, res, next) ->
  r = false
  method = req.method.toLowerCase().replace(/delete/, 'del')
  switch method
    when 'get', 'post', 'del', 'put'
      r = request[method](
        uri: process.env.PROXY_URL + req.url
        json: req.body)
    else
      return res.send('invalid method')
  req.pipe(r).pipe res

자바 스크립트 :

app.use(function(req, res, next) {
  var method, r;
  method = req.method.toLowerCase().replace(/delete/,"del");
  switch (method) {
    case "get":
    case "post":
    case "del":
    case "put":
      r = request[method]({
        uri: process.env.PROXY_URL + req.url,
        json: req.body
      });
      break;
    default:
      return res.send("invalid method");
  }
  return req.pipe(r).pipe(res);
});