node 本地伺服器實現前端介面代理,轉發

泥猴桃發表於2018-12-19

如果專案是用 react webpack 搭建的,或者是vue-cli 搭建的話,webpack配置中的proxy外掛就可以實現伺服器代理。
但是如果平時開發一些簡單的頁面,幾個頁面的小專案,但是也涉及到和後端的資料互動,我們還想做代理轉發的話,比較常用的就是nginx 或者nodejs 了。
這裡我只寫了 node 的實現方法,

1.

https://github.com/jiangzhenfei/server 下載,包括 proxy-conf.js 檔案和 server.js 檔案,複製到你需要代理的頁面的目錄,一般是index.html目錄,

2.

配置 proxy-conf.js 檔案:如下僅供參考

//代理配置
let conifg = {
    '/kdcos/':{   //將/kdcos/開頭的請求代理到http://172.24.4.220:80這臺伺服器(類似於vue的代理配置)
        target: 'http://172.24.4.220:80',
    },
    '/osm/':{     //將/osm/開頭的請求代理到http://120.79.90.199:80這臺伺服器
        target: 'http://120.79.90.199:80',
    }
}
module.exports = conifg  //匯出配置檔案

3.

在當前目錄命令列輸入node server.js即可。

下面就是具體如何實現的,有興趣的可以看看。並不影響使用

1.首先我們介紹如何啟動伺服器並且顯示本地的頁面

1.1如何起伺服器(檔案為index.js)

let http  = require('http')

let app = http.createServer ( function(request,response){
    let url = request.url
    if(request.url!=='/favicon.ico'){//清除第二次訪問
        response.end('hello world!')
    }
} ) 
app.listen(8000)

這個時候我們在當前的目錄命令列輸入 node index.js,這個時候開啟瀏覽器輸入localhost:8000,就可以在頁面看大hello world!.

1.2 基於上面的思路,我們可以通過檔案讀取的方式將本地的index.html檔案讀取然後傳入respones.end()

let http  = require('http')

let app = http.createServer ( function(request,response){
    let url = request.url
    if(request.url!=='/favicon.ico'){//清除第二次訪問//正常的讀取檔案和其他資源載入
        fs.readFile( __dirname + ( url==='/' ? '/index.html':url ), function( err, data ){
            if( err ){
                console.log( 'file-err',err )
            }else{
                response.end( data )
            }
        });
    }
} )

當輸入localhost:8000或者localhost:8000/index.html也面就會出現當前所在目錄的index.html頁面,因為我們讀取了該頁面相應給該埠。

2.如何實現介面的轉發

以上我們實現啟動本地伺服器展現頁面,但是頁面中的ajax介面如何實現轉發呢,比如我的url為/osm/client/sort的路由需要轉發到http://120.79.90.199:80這臺伺服器上,我們該如何實現呢

2.1使用http.request實現介面的轉發

var http = require('http')
var opt = {
   host:'這裡放代理伺服器的ip或者域名',
   port:'這裡放代理伺服器的埠號',
   method:'POST',//這裡是傳送的方法
   path:' https://www.google.com',     //這裡是訪問的路徑
   headers:{
    //這裡放期望傳送出去的請求頭
   }
}
//以下是接受資料的程式碼
var body = '';
var req = http.request(opt, function(res) {
    console.log("Got response: " + res.statusCode);
    res.on('data',function(d){
    body += d;
   }).on('end', function(){
      console.log(res.headers)
      console.log(body)
   });
}).on('error', function(e) {
  console.log("Got error: " + e.message);
})
req.end();

2.2監聽頁面中的http請求,檢視是否存在需要轉發的介面,利用上述方法轉發得到結果後返回前臺(server.js)

let http  = require('http')
let fs = require('fs')

//哪些url請求需要代理(代理配置)
let conifg = {
    '/kdcos/':{//   /kdcos/開頭的url需要代理到http://172.24.4.220:80這臺伺服器
        target: 'http://172.24.4.220:80',
    },
    '/osm/':{
        target: 'http://120.79.90.199:80',
    }
}

let app = http.createServer ( function(request,response){
    let url = request.url
    if(request.url!=='/favicon.ico'){//清除第二次訪問
        //請求的資料是否存在代理
        for ( var key in conifg){
            if( url.indexOf(key) >-1 ){
                let info = conifg[key].target.split(':')
                let opt = {
                    protocol: info[0]+':',
                    host:    info[1].slice(2),
                    port:    info[2] || 80,
                    method:  request.method,//這裡是傳送的方法
                    path:    url,     //這裡是訪問的路徑
                    json: true,
                    headers: request.headers
                }
                proxy( opt, response,request )//代理方法
                return;
            }
        }
        //正常的讀取檔案和其他資源載入
        fs.readFile( __dirname + ( url==='/' ? '/index.html':url ), function( err, data ){
            if( err ){
                console.log( 'file-err',err )
            }else{
                console.log(data)
                response.end( data )
            }
        });
    }
} ) 

//代理轉發的方法
function proxy( opt,res ,req){
    var proxyRequest = http.request(opt, function(proxyResponse) { //代理請求獲取的資料再返回給本地res
        proxyResponse.on('data', function(chunk) {
            console.log( chunk.toString('utf-8') )
            res.write(chunk, 'binary');
        });
        //當代理請求不再收到新的資料,告知本地res資料寫入完畢。
        proxyResponse.on('end', function() {
            res.end();
        });
        res.writeHead(proxyResponse.statusCode, proxyResponse.headers);
    }); 
    //data只有當請求體資料進來時才會觸發
    //儘管沒有請求體資料進來,data還是要寫,否則不會觸發end事件
    req.on('data', function(chunk) {
        console.log('in request length:', chunk.length);
        proxyRequest.write(chunk, 'binary');
    });
    req.on('end', function() {
        //向proxy傳送求情,這裡end方法必須被呼叫才能發起代理請求
        //所有的客戶端請求都需要通過end來發起
        proxyRequest.end();
    }); 
}

app.listen(8000)
console.log('server is listen on 8000....')

現在我們在當前目錄命令列輸入 node server.js,瀏覽器開啟localhost:8000就可以看到頁面。

2.3現在看看我們的index.html頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>
</head>
<body>
    <h1>hahah</h1>
    <button class="button"> hahh </button>
    <button class="button2"> hahh </button>
    <script src="./a.js"></script>
    <script>
        $('.button').click( function(){
            $.ajax({
                url:'/kdcos/app/service?page=1&pageSize=5&name=',
                headers:{
                    "x-auth-token": "6491f900-a968-41b4-b56b-778eca4eb8b1",
                },
                success:function(e){
                }
            })
        } )
        $('.button2').click( function(){
            $.ajax({
                url:'/osm/client/sort',
                success:function(e){ 
                }
            })
        } )
    </script>
</body>
</html>

我們點選頁面中的按鈕1和按鈕2,就可以看到不同的返回,來自兩臺不同的伺服器。

最後在附一份nginx 代理的部落格
https://www.cnblogs.com/zhenfei-jiang/p/9337141.html

相關文章