首頁  >  文章  >  web前端  >  node和express搭建代理伺服器的方法介紹

node和express搭建代理伺服器的方法介紹

不言
不言轉載
2019-01-11 11:33:404309瀏覽

這篇文章帶給大家的內容是關於node和express搭建代理伺服器的方法介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

本範例用node和express搭建的代理伺服器。 ,期望目標如下:

1、開啟某服務A,該服務可實現若干功能,例如普通的restful請求,文件上傳,靜態資源存取等等。

2、開啟node代理服務B,指向服務A,存取代理服務B,可存取服務A的任意功能。

就如下圖所示:

node和express搭建代理伺服器的方法介紹

#圖中上半部是直接存取服務,下班部分是透過代理伺服器訪問服務。

使用代理伺服器時,瀏覽器向代理伺服器請求數據,代理伺服器轉發請求,並將接收到的資料傳回瀏覽器,即所有的資料都透過代理伺服器轉送。
帶著這個目標,我們就講述下如何實現該功能。

既然是請求和回應轉發,那我們就了解一下,什麼是請求。

請求和回應簡述

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;

上面就是node代理的核心程式碼。支援普通的請求,靜態資源代理,文件上傳下載代理等功能。

git 位址:https://github.com/xubaodian/...

demo中,核心程式碼在common/proxy. js裡,我還實作了兩個測試服務。

在server檔案下的app.js和app2.js是兩個服務的入口檔案。

app2.js是目標伺服器,有三個測試頁面

1、http://localhost:20000/json.html post請求測試,對應'/json'接口,可發送數據,f12查看請求是否成功

2、http://localhost:20000/upload.html 文件上傳測試,對應接口'/upload'接口,上傳文件,f12查看請求是否成功,同時在伺服器upload資料夾下會有檔案。

3、http://localhost:20000/get.html  get請求測試,對應介面'/get',同樣f12查看

app2為目標伺服器,有3個介面。

1、'/upload'接口,測試文件上傳功能,上傳文件將放在uploads資料夾下,上傳的文件,文件名是一個uuid,沒有後綴,添加後綴即可查看文件是完整。測試過,傳1G的文件沒問題,再大的文件沒試過,有需要的可以試試

#2、'/json',測試POST請求。

3、'/get',測試GET請求。

app.js為代理服務為器,監聽埠為18000,將所有請求轉送至app2,即所有app2的介面靜態資源,app中存取時一致的。

測試步驟:
1、可開啟目標伺服器,透過三個頁面測試功能。

2、開啟代理伺服器,造訪以下三個頁面:

http://localhost:18000/json.html

http://localhost:18000/upload .html

http://localhost:18000/get.html

測試相同的功能。若和步驟1實現同樣功能,則代理服務功能已經實現了。

經過測試,代理功能是沒問題的。

如果問題歡迎留言,或寄信至472784995@qq.com。

至於效能,我沒測過,因為我自己這邊的應用場景,訪問量都不大,可以使用。

#

以上是node和express搭建代理伺服器的方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除