node和express如何搭建代理服務(wù)器

這篇文章將為大家詳細(xì)講解有關(guān)node和express如何搭建代理服務(wù)器,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站建設(shè)、成都做網(wǎng)站、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)建站是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)建站推出良慶免費(fèi)做網(wǎng)站回饋大家。



本例用node和express搭建的代理服務(wù)器。期望目標(biāo)如下:

1、開(kāi)啟某服務(wù)A,該服務(wù)可實(shí)現(xiàn)若干功能,例如普通的restful請(qǐng)求,文件上傳,靜態(tài)資源訪問(wèn)等等。

2、開(kāi)啟node代理服務(wù)B,指向服務(wù)A,訪問(wèn)代理服務(wù)B,可訪問(wèn)服務(wù)A的任意功能。

就如下圖所示:

node和express如何搭建代理服務(wù)器

圖中上半部分是直接訪問(wèn)服務(wù),下班部分是通過(guò)代理服務(wù)器訪問(wèn)服務(wù)。

使用代理服務(wù)器時(shí),瀏覽器向代理服務(wù)器請(qǐng)求數(shù)據(jù),代理服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求,并將接收到的數(shù)據(jù)返回給瀏覽器,即所有的數(shù)據(jù)都通過(guò)代理服務(wù)器轉(zhuǎn)發(fā)。
帶著這個(gè)目標(biāo),我們就講述下如何實(shí)現(xiàn)該功能。

既然是請(qǐng)求和響應(yīng)轉(zhuǎn)發(fā),那我們就了解一下,什么是請(qǐng)求。

請(qǐng)求和響應(yīng)簡(jiǎn)述

http請(qǐng)求和響應(yīng)主要右報(bào)文頭部、空行和報(bào)文主體三個(gè)部分組成。

空行我們不用關(guān)心,其實(shí)對(duì)我們來(lái)說(shuō),只要完成報(bào)文頭部和報(bào)文主體的轉(zhuǎn)發(fā),就可以說(shuō)實(shí)現(xiàn)了代理功能。

請(qǐng)求和響應(yīng)通過(guò)代理的整個(gè)過(guò)程如下:

1、代理服務(wù)器接收請(qǐng)求后,在將目標(biāo)服務(wù)數(shù)據(jù)返回給瀏覽器前要保持請(qǐng)求。

2、提取請(qǐng)求路徑、請(qǐng)求頭、請(qǐng)求主體等數(shù)據(jù)。

3、以2中提取的數(shù)據(jù)為參數(shù),向目標(biāo)服務(wù)器發(fā)送請(qǐng)求。

4、接收目標(biāo)服務(wù)器返回?cái)?shù)據(jù),提取響應(yīng)頭,響應(yīng)主體等數(shù)據(jù)。

5、將4中的提取出來(lái)的數(shù)據(jù)返回給客戶端(瀏覽器)。

6、斷開(kāi)連接。

經(jīng)過(guò)這幾個(gè)步驟,就實(shí)現(xiàn)了代理。

代碼實(shí)現(xiàn)

下面直接上代碼,然后做一些講解。代理函數(shù)如下:

const http = require('http');
const querystring = require('querystring');

//獲取請(qǐng)求的cookie和query等
let getHeader = (reqClient) => {
    let headers = reqClient.headers; 
    headers.path = reqClient.path;
    headers.query = reqClient.query;
    headers.cookie = reqClient.get('cookie') || '';

    return headers;
}

//代理函數(shù),options是代理設(shè)置,包括目標(biāo)服務(wù)器ip,port等
let proxy = (options) => {
    let reqOptions = {
        hostname: options.host,
        port: options.port
    }
    //返回請(qǐng)求處理函數(shù),reqClient瀏覽器的請(qǐng)求,resClient是響應(yīng)瀏覽器的對(duì)象
    return function (reqClient, resClient) {
        //設(shè)置目標(biāo)服務(wù)器的請(qǐng)求參數(shù),頭中的各項(xiàng)參數(shù)
        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;
        //向目標(biāo)服務(wù)器發(fā)送請(qǐng)求,reqProxy是向目標(biāo)服務(wù)器的請(qǐng)求,resProxy是目標(biāo)服務(wù)器的響應(yīng)。
        let reqProxy = http.request(reqOptions, (resProxy) => {
            resProxy.setEncoding('utf8');
            //設(shè)置返回http頭
            resClient.set(resProxy.headers);
            resClient.status(resProxy.statusCode);
            //接收從目標(biāo)服務(wù)器返回的數(shù)據(jù)
            resProxy.on('data', (chunk) => {
                //接收目標(biāo)服務(wù)器數(shù)據(jù)后,以流的方式向?yàn)g覽器返回?cái)?shù)據(jù)
                resClient.write(chunk);
            });

            //接收目標(biāo)服務(wù)器數(shù)據(jù)結(jié)束
            resProxy.on('end', () => {
                //向?yàn)g覽器寫數(shù)據(jù)結(jié)束。
                resClient.end();
            });
            //目標(biāo)服務(wù)器響應(yīng)錯(cuò)誤
            resProxy.on('error', () => {
                //響應(yīng)錯(cuò)誤,結(jié)束向?yàn)g覽器返回?cái)?shù)據(jù)
                resClient.end();
            });
        });

        //接收瀏覽器數(shù)據(jù)
        reqClient.on('data', (chunk) => {
           //以流的方式向目標(biāo)服務(wù)器發(fā)送數(shù)據(jù)
            reqProxy.write(chunk);
        });
        //接收數(shù)據(jù)結(jié)束
        reqClient.on('end', () => {
          //向目標(biāo)服務(wù)器寫數(shù)據(jù)結(jié)束
            reqProxy.end();
        });
        
        //普通JSON數(shù)據(jù)代理
         if (Object.keys(reqClient.body).length) {
             reqProxy.write(querystring.stringify(reqClient.body));
             reqProxy.end();
         }
    }
}

module.exports = proxy;

上面就是node代理的核心代碼。支持普通的請(qǐng)求,靜態(tài)資源代理,文件上傳下載代理等功能。

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

demo中,核心代碼在common/proxy.js里,我還實(shí)現(xiàn)了兩個(gè)測(cè)試服務(wù)。

在server文件下的app.js和app2.js是兩個(gè)服務(wù)的入口文件。

app2.js是目標(biāo)服務(wù)器,有三個(gè)測(cè)試頁(yè)面

1、http://localhost:20000/json.html post請(qǐng)求測(cè)試,對(duì)應(yīng)'/json'接口,可發(fā)送數(shù)據(jù),f12查看請(qǐng)求是否成功

2、http://localhost:20000/upload.html 文件上傳測(cè)試,對(duì)應(yīng)接口'/upload'接口,上傳文件,f12查看請(qǐng)求是否成功,同時(shí)在服務(wù)器upload文件夾下會(huì)有文件。

3、http://localhost:20000/get.html  get請(qǐng)求測(cè)試,對(duì)應(yīng)接口'/get',同樣f12查看

app2為目標(biāo)服務(wù)器,有3個(gè)接口。

1、'/upload'接口,測(cè)試文件上傳功能,上傳文件將放在uploads文件夾下,上傳的文件,文件名是一個(gè)uuid,沒(méi)有后綴,添加后綴即可查看文件是完整。測(cè)試過(guò),傳1G的文件沒(méi)問(wèn)題,再大的文件沒(méi)試過(guò),有需要的可以試下

2、'/json',測(cè)試POST請(qǐng)求。

3、'/get',測(cè)試GET請(qǐng)求。

app.js為代理服務(wù)為器,監(jiān)聽(tīng)端口為18000,將所有請(qǐng)求轉(zhuǎn)發(fā)至app2,即所有app2的接口靜態(tài)資源,app中訪問(wèn)時(shí)一致的。

測(cè)試步驟:
1、可開(kāi)啟目標(biāo)服務(wù)器,通過(guò)三個(gè)頁(yè)面測(cè)試功能。

2、開(kāi)啟代理服務(wù)器,訪問(wèn)下面三個(gè)頁(yè)面:

http://localhost:18000/json.html

http://localhost:18000/upload.html

http://localhost:18000/get.html

測(cè)試同樣的功能。若和步驟1實(shí)現(xiàn)同樣功能,則代理服務(wù)功能已經(jīng)實(shí)現(xiàn)了。

經(jīng)過(guò)測(cè)試,代理功能是沒(méi)問(wèn)題的。

如果問(wèn)題歡迎留言,或發(fā)送郵件至472784995@qq.com。

至于性能,我沒(méi)測(cè)過(guò),因?yàn)槲易约哼@邊的應(yīng)用場(chǎng)景,訪問(wèn)量都不大,可以使用。

關(guān)于node和express如何搭建代理服務(wù)器就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)站欄目:node和express如何搭建代理服務(wù)器
文章起源:http://muchs.cn/article36/piecsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、虛擬主機(jī)網(wǎng)站營(yíng)銷、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管