express.js를 사용하는 프록시
동일한 도메인 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
});
});
그러나 원래 웹 서버(또는 최종 사용자)에 반환되는 내용이 없으므로 운이 없습니다.
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);
참고: @MaxPRAPerty에서 언급한 바와 같이,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
원격 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();
});
주의: 위의 내용을 실제로 시도하지 않았기 때문에 구문 분석 오류가 포함되어 있을 수 있습니다. 이를 통해 작동 방법에 대한 힌트를 얻을 수 있기를 바랍니다.
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);
});
다음 설정을 사용하여 모든 작업을 수행했습니다./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
그런 다음 서버에서 .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/http://localhost:8080/api/http로 리디렉션합니다.
좋아요. 하드코딩된 프록시 대신 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
Javascript:
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);
});
원하는 것을 정확히 수행하는 짧은 솔루션을 찾았습니다. https://github.com/http-party/node-http-proxy
설치 후http-proxy
npm install http-proxy --save
서버/인덱스/app.js에서 아래와 같이 사용합니다.
var proxyServer = require('http-route-proxy');
app.use('/api/BLABLA/', proxyServer.connect({
to: 'other_domain.com:3000/BLABLA',
https: true,
route: ['/']
}));
저는 정말로 이 문제를 피하기 위해 여러 곳을 찾아다녔고, 많은 해결책을 시도했지만 이것 외에는 아무 것도 효과가 없었습니다.
그것이 다른 누군가에게도 도움이 되기를 바랍니다 :)
저는 특별한 샘플은 없지만, 플레인이 있는 것은 있습니다.http-proxy
입니다.블로그에 사용했던 프록시를 아주 삭제한 버전입니다.
즉, 모든 nodejs http 프록시 패키지는 tcp(소켓) 수준이 아닌 http 프로토콜 수준에서 작동합니다.이는 고속 및 모든 고속 미들웨어에도 해당됩니다.이들 중 누구도 투명 프록시를 수행할 수 없으며 백엔드 웹 서버로 전송되는 패킷에 수신 트래픽 소스 IP를 유지하는 NAT도 수행할 수 없습니다.
그러나 웹 서버는 http x 전달 헤더에서 원본 IP를 가져와 로그에 추가할 수 있습니다.
그xfwd: true
proxyOption
에 대해 사용http-proxy
.
const url = require('url');
const proxy = require('http-proxy');
proxyConfig = {
httpPort: 8888,
proxyOptions: {
target: {
host: 'example.com',
port: 80
},
xfwd: true // <--- This is what you are looking for.
}
};
function startProxy() {
proxy
.createServer(proxyConfig.proxyOptions)
.listen(proxyConfig.httpPort, '0.0.0.0');
}
startProxy();
X-Forwarded 헤더에 대한 참조: https://en.wikipedia.org/wiki/X-Forwarded-For
내 프록시의 전체 버전: https://github.com/J-Siu/ghost-https-nodejs-proxy
저는 프록시 요청을 더 잘 제어할 수 있는 방법을 알아냈습니다.
프록시 서버에서 요청한 응답은 xios를 사용하여 스트림 형식으로 클라이언트에 파이프라인으로 연결됩니다.
클라이언트에서 더 많은 정보를 프록시 서버를 통해 전달하기 위해 더 많은 헤더 및 데이터 본문 제어를 수행할 수 있습니다.
// proxy.js
import { Router } from "express";
var router = Router();
import axios from "axios";
// Proxy the request
router.all("/", async function (req, res, next) {
let url = req.body["url"];
let method = req.body["method"] ? req.body["method"] : "GET";
let headers = req.body["headers"] ? req.body["headers"] : null;
let params = req.body["params"] ? req.body["params"] : null;
let data = req.body["data"] ? req.body["data"] : null;
const response = await axios({
method: method,
url: url,
headers: headers,
params: params,
data: data,
responseType: "stream",
});
// Set the header of response as the header of the proxy response
for (let key in response.headers) {
res.setHeader(key, response.headers[key]);
}
// Pipe the response to the client
const stream = response.data;
stream.pipe(res);
});
export default router;
// client.js
fetch("http://localhost:3000/proxy", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
url: picURL,
method: "GET",
headers: { Host: "wx2.sinaimg.cn" },
}),
}).then(async (res) => {
const blobURL = URL.createObjectURL(await res.blob());
});
제 생각에 당신은 사용해야 할 것 같습니다.cors npm
const app = express();
const cors = require('cors');
var corsOptions = {
origin: 'http://localhost:3000',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions));
https://www.npmjs.com/package/cors
언급URL : https://stackoverflow.com/questions/10435407/proxy-with-express-js
'programing' 카테고리의 다른 글
임의의 영숫자 문자열을 생성하려면 어떻게 해야 합니까? (0) | 2023.05.13 |
---|---|
SQL Azure - 데이터베이스 간에 표 복사 (0) | 2023.05.13 |
bower init - amd, es6, 글로벌 및 노드 간의 차이 (0) | 2023.05.08 |
없는 경우 폴더 경로 만들기(VBA에서 저장) (0) | 2023.05.08 |
설치 시 최신 버전의 Xcode가 고착됨(12.5) (0) | 2023.05.08 |