이 기사는 노드와 익스프레스를 사용하여 프록시 서버를 설정하는 방법을 소개합니다. 이는 특정 참고 가치가 있으므로 도움이 필요한 친구에게 도움이 되기를 바랍니다.
이 예에서는 node 및 express로 구축된 프록시 서버를 사용합니다. , 예상되는 목표는 다음과 같습니다.
1. 일반 휴식 요청, 파일 업로드, 정적 리소스 액세스 등과 같은 여러 기능을 구현할 수 있는 서비스 A를 엽니다.
2. 노드 프록시 서비스 B를 열고, 서비스 A를 가리키고, 프록시 서비스 B에 액세스하고, 서비스 A의 모든 기능에 액세스합니다.
아래 그림과 같이
그림의 위쪽 부분은 서비스에 직접 접속하는 부분이고, 비번 부분은 프록시 서버를 통해 서비스에 접속하는 부분입니다.
프록시 서버를 사용하는 경우 브라우저는 프록시 서버에 데이터를 요청하고, 프록시 서버는 요청을 전달하고 수신된 데이터를 브라우저에 반환합니다. 즉, 모든 데이터가 프록시 서버를 통해 전달됩니다.
이 목표를 염두에 두고 이 기능을 구현하는 방법을 설명하겠습니다.
요청 및 응답 전달이므로 요청이 무엇인지 알아보겠습니다.
http 요청 및 응답은 주로 메시지 헤더, 빈 줄, 메시지 본문의 세 부분으로 구성됩니다.
빈 줄은 신경 쓸 필요가 없습니다. 사실 우리 입장에서는 메시지 헤더와 메시지 본문 전달만 완료하면 프록시 기능이 구현되었다고 할 수 있습니다.
프록시를 통한 요청 및 응답의 전체 과정은 다음과 같습니다.
1. 프록시 서버는 요청을 받은 후 대상 서비스 데이터를 브라우저에 반환하기 전에 요청을 유지해야 합니다.
2. 요청 경로, 요청 헤더, 요청 본문 및 기타 데이터를 추출합니다.
3. 2에서 추출한 데이터를 매개변수로 사용하여 대상 서버에 요청을 보냅니다.
4. 대상 서버에서 반환된 데이터를 수신하고 응답 헤더, 응답 본문 및 기타 데이터를 추출합니다.
5. 4에서 추출한 데이터를 클라이언트(브라우저)에 반환합니다.
6. 연결을 끊습니다.
이러한 단계를 거쳐 에이전트가 구현됩니다.
코드로 직접 가서 설명을 해보자. 에이전트 기능은 다음과 같습니다.
const http = require('http'); const querystring = require('querystring'); //获取请求的cookie和query等 let getHeader = (reqClient) => { let headers = reqClient.headers; headers.path = reqClient.path; headers.query = reqClient.query; headers.cookie = reqClient.get('cookie') || ''; return headers; } //代理函数,options是代理设置,包括目标服务器ip,port等 let proxy = (options) => { let reqOptions = { hostname: options.host, port: options.port } //返回请求处理函数,reqClient浏览器的请求,resClient是响应浏览器的对象 return function (reqClient, resClient) { //设置目标服务器的请求参数,头中的各项参数 let headers = getHeader(reqClient); reqOptions.headers = reqClient.headers; let query = []; if (headers.query) { Object.keys(headers.query).map(key => { query.push(key + '=' + headers.query[key]); }); reqOptions.path = headers.path + (query.length === 0 ? '' : ('?' + query.join('&'))); } reqOptions.cookie = headers.cookie; reqOptions.method = reqClient.method; //向目标服务器发送请求,reqProxy是向目标服务器的请求,resProxy是目标服务器的响应。 let reqProxy = http.request(reqOptions, (resProxy) => { resProxy.setEncoding('utf8'); //设置返回http头 resClient.set(resProxy.headers); resClient.status(resProxy.statusCode); //接收从目标服务器返回的数据 resProxy.on('data', (chunk) => { //接收目标服务器数据后,以流的方式向浏览器返回数据 resClient.write(chunk); }); //接收目标服务器数据结束 resProxy.on('end', () => { //向浏览器写数据结束。 resClient.end(); }); //目标服务器响应错误 resProxy.on('error', () => { //响应错误,结束向浏览器返回数据 resClient.end(); }); }); //接收浏览器数据 reqClient.on('data', (chunk) => { //以流的方式向目标服务器发送数据 reqProxy.write(chunk); }); //接收数据结束 reqClient.on('end', () => { //向目标服务器写数据结束 reqProxy.end(); }); //普通JSON数据代理 if (Object.keys(reqClient.body).length) { reqProxy.write(querystring.stringify(reqClient.body)); reqProxy.end(); } } } module.exports = proxy;
위는 노드 에이전트의 핵심 코드입니다. 일반 요청, 정적 리소스 프록시, 파일 업로드 및 다운로드 프록시 및 기타 기능을 지원합니다.
git 주소: https://github.com/xubaodian/...
데모에서 핵심 코드는 common/proxy.js에 있고, 테스트 서비스 2개도 구현해 봤습니다.
서버 파일 아래 app.js와 app2.js는 두 서비스의 항목 파일입니다.
app2.js는 대상 서버이며 3개의 테스트 페이지가 있습니다
1. http://localhost:20000/json.html 게시 요청 테스트는 '/json' 인터페이스에 해당하며, f12에 데이터를 보낼 수 있습니다. 요청이 성공했는지 확인하세요
2. http://localhost:20000/upload.html 파일 업로드 테스트, '/upload' 인터페이스에 해당하는 파일 업로드, f12를 통해 요청이 성공했는지 확인합니다. 서버의 업로드 폴더에 파일이 있어야 합니다.
3. http://localhost:20000/get.html get 요청 테스트, '/get' 인터페이스에 해당, 마찬가지로 f12 보기
app2는 3개의 인터페이스가 있는 대상 서버입니다.
1. '/upload' 인터페이스에서 파일 업로드 기능을 테스트합니다. 업로드된 파일의 파일 이름은 접미사 없이 UUID입니다. 완벽한. 테스트를 거쳤으며 1G 파일 전송에는 문제가 없습니다. 파일이 아무리 크더라도 시도하지 않았습니다. 필요한 경우
2, '/json'을 시도하여 POST 요청을 테스트할 수 있습니다.
3. '/get', GET 요청을 테스트합니다.
app.js는 프록시 서버이고 수신 포트는 18000이며 모든 요청은 app2로 전달됩니다. 즉, app2의 모든 인터페이스 정적 리소스는 앱에서 액세스할 때 일관됩니다.
테스트 단계:
1. 대상 서버를 열고 세 페이지를 통해 기능을 테스트합니다.
2. 프록시 서버를 켜고 다음 세 페이지를 방문하세요:
http://localhost:18000/json.html
http://localhost:18000/upload.html
http://localhost: 18000/ get.html
동일한 기능을 테스트해 보세요. 1단계와 동일한 기능이 구현되면 프록시 서비스 기능이 구현된 것입니다.
테스트 결과 프록시 기능에는 문제가 없습니다.
궁금한 점이 있으시면 메시지를 남기시거나 472784995@qq.com으로 이메일을 보내주세요.
성능에 관해서는 제가 직접 만든 응용 시나리오는 방문 횟수가 많지 않아 사용할 수 있기 때문에 테스트하지 않았습니다.
위 내용은 노드와 익스프레스를 사용하여 프록시 서버를 구축하는 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!