koa進階史(一)

1,設置靜態文件目錄,將__dirname 寫成_dirname,乍看沒什麼毛病,可是一運行以後發現,_dirname is not defined,下次注意哈html

app.use(express.static(__dirname + '/public'));
該__dirname是node的一個全局變量,表示當前模塊的文件夾名稱。
相對的__filename,當前模塊的文件名稱---解析後的絕對路徑。
app.use(serve(path.join(__dirname, 'public/src')));path.join是用於兩個文件夾路徑的拼接,path.resolve相似於linux命令的cd。
 
2,用koa-router進行post請求時候拿不到請求數據,原來,koa用post請求URL時,post會發送表單或者json,做爲request的body發送,node仍是koa的request對象都不提供解析request的body對象,必須用中間件進行解析。koa提供了koa-parser中間件進行解析原始的request對象。
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());

須要注意的是:該middleware的順序很重要,必須在router以前被註冊到app對象上。至此就拿到了這個ctx.request.body對象,就是咱們的請求數據。前端

  3,說個比較傻傻的問題,昨天是用node的request獲取後臺接口,返回是有了,可是由於後臺接口要過cas校驗,也就是要登陸域帳號,若是後臺接口的status是302,就要重定向到相應的location,剛剛解決了這個問題,至此在記錄下。
(1)在node中間層我未可以轉發服務成功的緣由是:koa是基於promise的,express是基於回調的,因此我在進行request方法調用的時候,須要返回一個promise對象。
(2)ctx.response的賦值是成功了,可是服務一直pending,一直覺得是由於ctx.end(),PS:ctx是沒有end的方法的。真是是由於個人promise沒有resolve或者reject,因此接口一直處於pending狀態,也就是promise的pending狀態,promise的中斷是須要進行resolve或者reject的。 
router 
 .get('/', pages.schedule)
 .get('/schedule', pages.schedule)
 .post('/schedule/getMeetingList/byWorkAndDate',function(ctx, next){
    let param = ctx.request.body;
    console.log('請求體===》',param)
    return new Promise((resolve,reject) => {
        request.post({
            url: byWorkAndDate,
            method: "POST",
            json: true,
            headers: {
                "content-type": "application/json",
            },
            body: JSON.stringify(param)
        },function(error,response,body){
            //重定向
            if(!error && response.statusCode == 302){
                ctx.response.status = 302;
                console.log("返回的response===>",response.headers)
                ctx.response.header = response.headers;
                ctx.response.body= null;
                console.log('ctx的設置是===》',ctx);
                let loc = response.headers.location;
                ctx.redirect('back',loc);
            }  
             
            if (!error && response.statusCode == 200) {
               ctx.body = res.body;
            }
            resolve()
        }); 
  })     
 })

4,可是重定向未跳轉成功,上面的3又進行了重組,我覺得問題都搞定了呢,其實沒有,在設置response.header的時候那種寫法是錯誤的,正確的寫法是:node

res.set(fields):使用對象同時設置 response header 中多個字段的值。

ctx.set({
  'Etag': '1234',
  'Last-Modified': date
});

代碼以下:linux

 router 
 .get('/', pages.schedule)
 .get('/schedule', pages.schedule)
 .post('/schedule/getMeetingList/byWorkAndDate',async (ctx, next)=>{  
           let param = ctx.request.body;  
           await requestData(byWorkAndDate,param).then(result=>{
            if(result[0] == 302){
                ctx.status = 302;
                ctx.set(result[1]);
                ctx.set({
                    "Referer":result[1].location
                })
                ctx.response.redirect(result[1].location);
            }
            console.log('ctx==>',ctx);
           });
           await next(); 
 })

上面的requestData是用request進行後臺請求接口數據的方法,而後resolve了兩個參數,一個是statusCode,另一個302時候是response.header,若是200就返回response.body。ajax

{
    request: {
        method: 'POST',
        url: '/schedule/getMeetingList/byWorkAndDate',
        header: {
            host: 'localhost:3000',
            connection: 'keep-alive',
            'content-length': '81',
            accept: '*/*',
            origin: 'http://localhost:3000',
            'x-requested-with': 'XMLHttpRequest',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
            'content-type': 'application/json;charset=UTF-8',
            referer: 'http://localhost:3000/',
            'accept-encoding': 'gzip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9',
            cookie: 'ESG_SFIM_SMS_SZ22_APP=ESG_SFIM_SMS_SZ22_JT_112_6'
        }
    },
    response: {
        status: 302,
        message: 'Found',
        header: {
            location: 'http://cas.sit.sf-express.com/cas/login?service=http://sfim-sms-bg.sit.sf-express.com/schedule/getMeetingList/byWorkAndDate',
            'content-length': '301',
            server: 'Jetty(9.2.7.v20150116)',
            'set-cookie': [Array],
            connection: 'close',
            via: '1.1 ID-0002262062176300 uproxy-7',
            referer: 'http://cas.sit.sf-express.com/cas/login?service=http://sfim-sms-bg.sit.sf-express.com/schedule/getMeetingList/byWorkAndDate',
            'content-type': 'text/html; charset=utf-8'
        }
    },
    app: {
        subdomainOffset: 2,
        proxy: false,
        env: 'development'
    },
    originalUrl: '/schedule/getMeetingList/byWorkAndDate',
    req: '<original node req>',
    res: '<original node res>',
    socket: '<original node socket>'
}

能夠看出ctx.response是完全被賦值成功,並且status是302,裏面的location是正常的跳轉連接。可是response.header裏面加了Referer跳轉仍然不成功;正在解決中。express

 5,重定向的問題是解決了,由於前端是ajax進行接口請求的,因此在status是302的時候,node中間層進行了重置,仍然statusCode返回200,可是ctx.body裏面的返回是:json

redirectUrl = result[1].location.split('?')[0]+'?service=http://localhost:3000';
ctx.body={status:302,location:redirectUrl}

在前端拿到返回的數據後,先判斷status的狀態,若是是302則進行location的跳轉,因此重定向是在前端作的。promise

目前node中間層開發過程當中遇到的問題就是CAS認證通不過,因此日程項目的改造通過一週的時間以失敗了結,由於SIT環境的CAS不支持本地服務的認證。cookie

可是在開發過程當中我進行了項目結構的模塊化:app

app.js   主要用來進行服務的啓動,中間件的引入。

router.js  主路由

routerMap.js  路由信息

server.js     後臺接口信息

 

【完】
 
知識就是力量。
相關文章
相關標籤/搜索