[Koa2 系列 04] Post 請求接收(中)

[Koa2 系列 04] Post 請求接收(中)

在上一篇知道了關於 post 方法的理論基礎
這一篇就來具體實現範例

先看看最終的程式碼

const Koa = require('koa')
const app = new Koa()
app.use(async (ctx) => {
    if(ctx.url==='/' && ctx.method==='GET') {
        let html=`
            <h1>JSPang Koa2 request POST</h1>
            <form method="POST" action="/">
                <p>userName</p>
                <input name="userName" /><br/>
                <p>age</p>
                <input name="age" /><br/>
                <p>website</p>
                <input name="webSite" /><br/>
                <button type="submit">submit</button>
            </form>
        `;
        ctx.body=html;
    }else if (ctx.url === '/' && ctx.method==='POST') {
        let pastData = await parsePostData(ctx);
         ctx.body = pastData;
    } else {
        ctx.body='<h1>404!</h1>';
    }

});

function parsePostData(ctx) {
    return new Promise((resolve,reject) => {
        try {
            let postdata="";
            ctx.req.addListener('data',(data)=>{
                postdata += data
            })
            ctx.req.on("end",function() {
                let parseData = parseQueryStr(postdata)
                resolve(parseData);
            })
        } catch (error) {
            reject(error);
        }
    });
}

function parseQueryStr(queryStr) {
    let queryData = {};
    let queryStrList = queryStr.split('&');
    console.log(queryStrList);
    for( let [index,queryStr] of queryStrList.entries()) {
        let itemList = queryStr.split('=');
        console.log(itemList);
        queryData[itemList[0]] = decodeURIComponent(itemList[1]);
    } 
    return queryData
}

app.listen(3000,() => {
    console.log('[demo] server is starting at port 3000');
});

使用 Node 原生方法取得 POST 參數

首先我們定義一個方法 parsePostData 接收上下文
並且使用 ES6 的 Promise 來處理

因為我們用了 promise 所以在主要區塊中處理 POST 請求的區塊
就使用 await 呼叫剛剛定義的方法

else  if (ctx.url === '/' && ctx.method === 'POST') {
	let  pastData = await  parsePostData(ctx);
	ctx.body = pastData;
}

上一篇中我們知道
ctx.req 是 nodejs 原生的方法,可以取得詳細請求內容

ctx.req.on 是 Koa 提供來監聽事件的方法
addListener 是原生的監聽事件方法

addListener

在上方程式碼中我們在資料有進來的時候監聽
把新進的資料賦予給預先定義好的變數 postdata

on

在程式結束 end 時監聽,把資料回傳

可以看到我分別使用 ES6 的箭頭函數
和一般的函數來操作兩個監聽器,作為一個比較

解析參數內容為 JSON 物件

這部分其實和 Koa2 就沒什麼關係了
parseQueryStr 就是把連接起來的參數字串 parse 成 JSON 物件
先用 & 把不同變數的值和鍵值分開存成陣列
再把陣列中的資料用 = 拆成 key - value 的形式
並且藉由 decodeURIComponent 方法,把原本被跳脫的字元轉換成原本的內容

最後就 resolve 回傳結果給 await 呼叫的函數
並印在畫面上,可以看到剛剛輸入的內容已經變成 JSON 型別了!

留言