最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Koa代理Http請求的示例代碼

 更新時間:2018年10月10日 09:07:52   作者:ChrysAwesome  
這篇文章主要介紹了Koa代理Http請求的示例代碼,詳解介紹了Koa 代理http請求,解決跨域問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Koa 代理http請求,解決跨域問題

1、為什么用Koa做跨域代理?

"最初為了解決跨域問題,我把站點部署到了nginx上就解決了問題。一次偶然的面試機會,面試官提出了一個假設(shè)我需要對提交api和api返回的數(shù)據(jù)進(jìn)行適配,那么nginx是不是就無法滿足了。當(dāng)然這個問題的提出,讓我考慮到其實如果自己搭一個站點,通過這個站點進(jìn)行轉(zhuǎn)發(fā),適配第三方api的請求和應(yīng)答不就好了。那么要搭一個站點的語言其實有很多,例如.net,java,nodejs,php...,那為什么最后選擇nodejs呢?對于我來說最重要的原因,應(yīng)該就是nodejs的輕量級和javascript語言親和性。

2、搭建nodejs應(yīng)用

由于Koa2剛出,畢竟學(xué)技術(shù),那么就學(xué)最新的。

既然搭建程序那么就從程序的入口開始做,首先寫程序的路由

const fs = require('fs')
const Router = require('koa-router');
const {httpHandle} = require('../Infrastructure/httpHandle');
const koaBody = require('koa-body')({
  multipart :true
});

const render = (page) => {
  return new Promise((resolve, reject) => {
    let viewUrl = `./view/${page}`
    fs.readFile(viewUrl, "binary", (err, data) => {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
}

let api = new Router();

api.get('*', httpHandle)
  .post('*', koaBody, httpHandle)
  .put('*', koaBody, httpHandle).del('*', koaBody, httpHandle);

let common = new Router();
common.get('*', async (ctx) => {
  ctx.body = await render('index.html');
})

let router = new Router();
router.use('/api', api.routes(), api.allowedMethods());
router.use('/', common.routes(), common.allowedMethods());
module.exports = router;

其次就是處理代理的請求

const httpRequest = (ctx) => {
  return new Promise((resolve) => {
    delete ctx.request.header.host;
    const options = {
      host,
      port,
      path: ctx.request.url.substr(4, ctx.request.url.length),
      method: ctx.request.method,
      headers: ctx.request.header
    }
    let requestBody='',
      body,
      head,
      chunks = [],
      fileFields,
      files,
      boundaryKey,
      boundary,
      endData,
      filesLength,
      totallength = 0;

    if (ctx.request.body) {
      console.log(ctx.request.header['content-type'])
      if (ctx.request.header['content-type'].indexOf('application/x-www-form-urlencoded') > -1) {
        requestBody = query.stringify(ctx.request.body);
        options.headers['Content-Length'] = Buffer.byteLength(requestBody)
      } else if (ctx.request.header['content-type'].indexOf('application/json') > -1) {
        requestBody = JSON.stringify(ctx.request.body);
        options.headers['Content-Length'] = Buffer.byteLength(requestBody)
      } else if (ctx.request.header['content-type'].indexOf('multipart/form-data') > -1) {
        fileFields = ctx.request.body.fields;
        files = ctx.request.body.files;
        boundaryKey = Math.random().toString(16);
        boundary = `\r\n----${boundaryKey}\r\n`;
        endData = `\r\n----${boundaryKey}--`;
        filesLength = 0;

        Object.keys(fileFields).forEach((key) => {
          requestBody += `${boundary}Content-Disposition:form-data;name="${key}"\r\n\r\n${fileFields[key]}`;
        })

        Object.keys(files).forEach((key) => {
          requestBody += `${boundary}Content-Type: application/octet-stream\r\nContent-Disposition: form-data; name="${key}";filename="${files[key].name}"\r\nContent-Transfer-Encoding: binary\r\n\r\n`;
          filesLength += Buffer.byteLength(requestBody,'utf-8') + files[key].size;
        })

        options.headers['Content-Type'] = `multipart/form-data; boundary=--${boundaryKey}`;
        options.headers[`Content-Length`] = filesLength + Buffer.byteLength(endData);
      } else {
        requestBody = JSON.stringify(ctx.request.body)
        options.headers['Content-Length'] = Buffer.byteLength(requestBody)
      }
    }

    const req = http.request(options, (res) => {
      res.on('data', (chunk) => {
        chunks.push(chunk);
        totallength += chunk.length;
      })

      res.on('end', () => {
        body = Buffer.concat(chunks, totallength);
        head = res.headers;
        resolve({head, body});
      })
    })

    ctx.request.body && req.write(requestBody);

    if (fileFields) {
      let filesArr = Object.keys(files);
      let uploadConnt = 0;
      filesArr.forEach((key) => {
        let fileStream = fs.createReadStream(files[key].path);
        fileStream.on('end', () => {
          fs.unlink(files[key].path);
          uploadConnt++;
          if (uploadConnt == filesArr.length) {
            req.end(endData)
          }
        })
        fileStream.pipe(req, {end: false})
      })
    } else {
      req.end();
    }

  })
}

由此簡單的幾行代碼就實現(xiàn)了通過nodejs實現(xiàn)跨域的請求代理。 github鏈接

nginx代理config配置 如下

server {
   listen     1024; 
   server_name   tigrex:1024;
   root      home/TuoTuo.v2.UI;
   index      index.html;
   access_log   logs/tigrex.access.log;
   error_log    logs/tigrex.error.log;

   charset     utf-8;
   
   location /api {
     proxy_pass  http://127.0.0.1:1023/;
     proxy_set_header Host $host;
     proxy_redirect off;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }  
   
   location / {
     try_files $uri $uri/ /index.html;     
    }
  }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • nodejs實現(xiàn)郵件發(fā)送服務(wù)實例分享

    nodejs實現(xiàn)郵件發(fā)送服務(wù)實例分享

    本文給大家講解的是簡單的使用nodejs搭建郵件發(fā)送服務(wù)的一個實例,非常的好用,有需要的小伙伴可以參考下
    2017-03-03
  • 使用nvm安裝node的詳細(xì)圖文教程

    使用nvm安裝node的詳細(xì)圖文教程

    nvm是nodejs的版本管理工具,可以在一個環(huán)境中同時安裝多個nodejs 版本(和配套的 npm 版本),并隨時切換,下面這篇文章主要給大家介紹了關(guān)于使用nvm安裝node的詳細(xì)圖文教程,需要的朋友可以參考下
    2023-02-02
  • Node.js(安裝,啟動,測試)

    Node.js(安裝,啟動,測試)

    這里主要介紹基于windows平臺上最簡單方便的安裝方式,啟動以及簡單測試
    2014-06-06
  • Node.js讀寫文件之批量替換圖片的實現(xiàn)方法

    Node.js讀寫文件之批量替換圖片的實現(xiàn)方法

    下面小編就為大家?guī)硪黄狽ode.js讀寫文件之批量替換圖片的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • node.js基于mongodb的搜索分頁示例

    node.js基于mongodb的搜索分頁示例

    本篇文章主要介紹了node.js基于mongodb的搜索分頁示例,mongodb分頁很簡單,這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下。
    2017-01-01
  • Node.js之構(gòu)建WebSocket服務(wù)全過程

    Node.js之構(gòu)建WebSocket服務(wù)全過程

    這篇文章主要介紹了Node.js之構(gòu)建WebSocket服務(wù)全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • NodeJS加密解密及node-rsa加密解密用法詳解

    NodeJS加密解密及node-rsa加密解密用法詳解

    要用nodejs開發(fā)接口,實現(xiàn)遠(yuǎn)程調(diào)用,如果裸奔太危險了,就在網(wǎng)上找了一下nodejs的加密,感覺node-rsa挺不錯的,下面來總結(jié)一下簡單的rsa加密解密用法,需要的朋友可以參考下
    2018-10-10
  • 淺談node node-sass sass-loader版本對應(yīng)問題

    淺談node node-sass sass-loader版本對應(yīng)問題

    本文主要介紹了淺談node node-sass sass-loader版本對應(yīng)問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Node.js重新刷新session過期時間的方法

    Node.js重新刷新session過期時間的方法

    在Node.js中,我們通常使用express-session這個包來使用和管理session,保存服務(wù)端和客戶端瀏覽器之間的會話狀態(tài)。那如何才能實現(xiàn)當(dāng)用戶刷新當(dāng)前頁面或者點擊頁面上的按鈕時重新刷新session的過期時間呢,接下來通過本文一起學(xué)習(xí)吧
    2016-02-02
  • node.js 抓取代理ip實例代碼

    node.js 抓取代理ip實例代碼

    這篇文章主要介紹了node.js 抓取代理ip實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04

最新評論

潼南县| 双辽市| 湖北省| 确山县| 丹巴县| 皋兰县| 潼关县| 庆阳市| 肇源县| 塔河县| 大安市| 双江| 东至县| 南通市| 临猗县| 平泉县| 朝阳县| 霍邱县| 搜索| 自贡市| 昌邑市| 北宁市| 西安市| 楚雄市| 闽清县| 靖州| 华池县| 西华县| 运城市| 天柱县| 襄樊市| 长泰县| 阜康市| 拉萨市| 曲阳县| 湟中县| 仪陇县| 邢台县| 澄江县| 阿拉尔市| 澄迈县|