koa2使用&&中間件&&angular2的koa托管


文章導航

1,koa2使用;

2,寫中間件;

3,koa2路由配置angular2;

 

一。先上代碼,一篇,看完koa2中大多基礎方法

const Koa=require('koa');
const app=new Koa();
    //middleWare:
const Router=require('koa-router');
const mount=require('koa-mount');
const staticCache=require('koa-static-cache');
const session=require('koa-session');
cosnt bodyParser=require('koa-bodyParser');
const send=require('koa-send');
const convert=require('koa-convert');
const co=require('co');



//使用bodyParser和session(following):
app.use(bodyParser());
app.keys=['mykeys'];
const sessionConfig={
      key:'myKey',   //cookie中的key命名為myKey。可以不定義使用默認值。
 }
app.use(convert(session(sessionConfig,app)));
app.use(co.wrap(function* (ctx,next){
     //自己定義了一個路由,接受url為 /myTest時,返回信息(following):
     if(ctx.path==='myTest'){
     //為其配備GET,POST方法(following):
         switch(ctx.method){
            case 'GET':
                ctx.session.views=++ctx.session.views||0;
                ctx.body=ctx.session.views;
            case 'POST':
                ctx.body=JSON.stringify(ctx.bodyParser);
           }
      }
     yield next();
}))


//使用路由中間件(following):
const router=new Router();
const childRouter=new Router();
childRouter.get(
     '/', 
     (ctx,next)=>{
         ctx.body='Child Content';
         return next();
     },
     (ctx,next)=>{
         ctx.body+='Attach Content';
      }
)
    //可以通過next,連用。也可以僅如下使用(following):
router.get('/', (ctx,next)=>{
      ctx.body='hello';
})
   //將兩個路由拼起來(following):
router.use(
   '/child', 
   childRouter.routes(),
   childRouter.allowedMethods()
)
 

app.use(mount( '/routerPath', router.routes()  ));
app.use(mount( '/routerPath', router.allowedMethods()));
  //(above)又將router,局限在‘routerPath’路徑。
app.use(mount( 
   '/static', 
   convert(staticCache(
        __dirname+'/static',
        {age:12000,usePrecompiledGzip:true} 
            //(above)在static下,托管目錄為static的靜態文件,設置cache-age=1200;並允許使用預先壓縮好的gzip      
      ));
))

//你也可以使用send,來單獨發送一個文件(following):
app.use (mount('/jquery.min.js', (ctx,next)=>{
     ctx.set( ' Content-Type','text/html');
     ctx.set( ' Content-Encoding', ' gzip');
     return send(ctx,'./js/jquery.min.js');  //jquery.min.js是gzip文件。
}))
//或者自己寫一個簡易(不判斷content-type)的具備koa-static功能的(following):
const fs=require('fs');
app.use( mount('/myStatic',(ctx,next)=>{
      let readStream=fs.createReadStream('./static'+ctx.path);
      ctx.body=readStream;
}))
//(above)通過ctx.path獲得/myStatic下的相對url。
// 在Http模塊下readStream.pipe(res);   而koa中ctx.body會自動處理流。


app.listen(3000);

 

二,自己寫一個中間件;

  比如我們只想對cookie進行加密和解密使用:

  myCookie.js:

const co=require('co');
const crypto=require('crypto');
const encrypt=function(val,key,method='aes192'){
      let cipher=crypto.createCipher(method,key);
      cipher.update(val,'utf8','hex');
      return cipher.final('hex');
}
const decrypt=function(val,key,method='aes192'){
      let deCipher=crypto.createDeCipher(method,key);
      deCipher.update(val,'hex','utf8');
      return cipher.final('utf8');
}

module.exports=function(key,method='aes192'){
      return co.wrap(function* (ctx,next){
            let originalSet=ctx.cookies.set.bind(ctx.cookies);
            let originalGet=ctx.cookies.get.bind(ctx.cookies);
            //重新定義cookies.set具備加密功能:
            ctx.cookies.set=function(...args){
                  try{
                         args[1]=encrypt(args[1],key,method);
                         originalSet(...args);
                  }catch(e){console.log(e)}
            }
            //重新定義cookies.get具備解密功能:
            ctx.cookies.get=function(...args){
                   try{
                         args[1]=decrypt(args[1],key,method);
                         originalGet(...args);
                   }catch(e){console.log(e)};
             }
            //增加一個清除cookie的功能:
            ctx.cookies.clear=function(name){
                   if(!name) return;
                   let d= new Date();
                   d.setTime(d.getTime()-1);
                   ctx.cookies.set(name, ' ' ,{expires:d});
           }
           yield next();  //最后別忘了yield next;
      } )
}

在app.js中使用:

const myCookie=require('./myCookie.js')('mykey');
app.use(myCookie);
app.keys=['mykey2'];
app.use((ctx)=>{
  ctx.cookies.set('name', 'Jnew ',{signed:true});
  ctx.cookies.clear('preName');
})

與普通ctx.cookies.set相同的用法,但是存入的cookie卻是經過加密的。

      signed:true時的解釋:

    The cookie will still be visible, but it has a signature, so it can detect if the client modified the cookie.

    It works by creating a HMAC of the value (current cookie), and base64 encoded it. When the cookie gets read, it recalculates the signature and makes sure that it matches the signature attached to it.

    If it does not match, then it will give an error.

    If you want to hide the contents of the cookie as well, you should encrypt it instead (or just stores it in the server side session). I'm not sure if there is middleware for that already out there or not.

server side session:

  PS:使用redis內存數據庫是一個比較好的解決方法。可是耗性能。就像我不用動態compress,而只是靜態托管已壓縮好的文件一樣。很早前就想過,將MVC這樣的構架從服務器中解脫出來,放在前端進行處理,畢竟服務器渲染HTML也是耗性能的。然后自己興致勃勃地寫了一個簡單的基於socket的前端模塊加載器,然后發現已經有了react 和后來angular2這樣的東西。畢竟我只是野路子的醫學生,那時又不愛逛社區。閉門造車真是可怕。。。- -!

三,托管Angular2前端路由:

frontEndComponent.js

const fs=require('fs');
const send=require('koa-send');

module.exports=function(path){
   return async(ctx,next)=>{
      let fileExist=await function(){
              return new Promose((resolve,reject)=>{
                     fs.access(path+ctx.path,err=>{
                        if(!!err||ctx.path==='/'){
                              resolve(false);
                         }else{
                               resolve(true);
                         }
                     })   
              })
      }();
      if (fileExist){   // typeof fileExist  :boolean  ..不是promise
           await send(ctx,path+ctx.path);  
      }else{
           await send(ctx,path+'/index.html');
      }          
   }
}

 不能直接托管於static下,因為瀏覽器中輸入地址時,前端路由會失效。根據地址判斷,服務器中對應的文件是否存在,不存在則返回index.html。該例使用async/await語法。需要babel編譯。

 app.js:

var frontEndComponent=require('./frontEndComponent');
var mount=require('koa-mount');
app.use(mount('/example-router',frontEndComponent('./dist')));
app.use((ctx)=>{
   ctx.body='empty';
})
app.listen(3000);

  后端將example-router這個地址及其子地址,分配給'/dist'目錄下的前端組件來管理。

      注意:index.html  中  <base href='/example-router/'>;

  我已經托管到npm,可以直接使用這個包:

   npm install koa-angular-proxy


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM