- 一個表單項目,獲取表單提交信息,展示在網(wǎng)頁上
用原生node寫網(wǎng)頁是真的麻煩
創(chuàng)建模塊
- 老套路 先創(chuàng)建模塊
輸出表單
const http = require('http');
http.createServer(function (req, res) {
res.writeHeader(200, {'Content-Type': 'text/html'});
res.end([
'<form method="post" action="/url">',
'<h1>My form</h1>',
'<fieldset>',
'<label>Personal Information</label>',
'<p>What is your name?</p>',
'<input type="text" name="name">',
'<p><button>Submit</button></p>',
'</form>'
].join(''));
}).listen(3000);
- 注意為了讓html結(jié)構(gòu)更加清楚,我們把響應(yīng)文本內(nèi)容寫在一個數(shù)組內(nèi),再用數(shù)組的
jion
的方法將其轉(zhuǎn)換為字符串 - 需要注意的是
<form>
標(biāo)簽中有/url
以及post
方法,另外輸入框內(nèi)還有個叫name
的名字 - 下面是運行效果
- 當(dāng)我們輸入內(nèi)容提交以后注意地址欄的變化
- 提交以后URL變了,不過響應(yīng)結(jié)果是一樣的,為了能讓node能夠?qū)Ρ韱翁峤坏恼埱笞龀稣_的處理,這里需要學(xué)習(xí)關(guān)于檢測請求方法和URL的相關(guān)內(nèi)容
method和URL
按邏輯,當(dāng)我們進(jìn)行提交的時候需要給用戶呈現(xiàn)一個不一樣的東西,這個時候我們需要處理表單
const http = require('http'); http.createServer(function (req, res) { if ('/' == req.url) { res.writeHeader(200, {'Content-Type': 'text/html'}); res.end([ '<form method="post" action="/url">', '<h1>My form</h1>', '<fieldset>', '<label>Personal Information</label>', '<p>What is your name?</p>', '<input type="text" name="name">', '<p><button>Submit</button></p>', '</form>' ].join('')); } else if ('/url' == req.url) { res.writeHeader(200, {'Content-Type': 'text/html'}); res.end(`you sent a ${req.method} request`) } }).listen(3000);
- 這個時候我們直接訪問是沒有什么變化的,當(dāng)我們直接訪問/url以后就會跳轉(zhuǎn)
- 當(dāng)我們提交以后就會
- 如上所示,我們這里接觸了兩個變量 URL 和 method
- Node會將主機(jī)名后所有的內(nèi)容都放在url屬性中
- 關(guān)于method有幾種不同的方法
- GET
- POST
- PUT
- DELETE
- PATCH
數(shù)據(jù)
當(dāng)發(fā)送html 的時候,需要隨著響應(yīng)體定義
Content-Type
頭信息const http = require('http'); http.createServer(function (req, res) { if ('/' == req.url) { res.writeHeader(200, {'Content-Type': 'text/html'}); res.end([ '<form method="post" action="/url">', '<h1>My form</h1>', '<fieldset>', '<label>Personal Information</label>', '<p>What is your name?</p>', '<input type="text" name="name">', '<p><button>Submit</button></p>', '</form>' ].join('')); } else if ('/url' == req.url && 'POST' == req.method) { let body = ''; req.on('data',function (chunk) { body += chunk; }); req.on('end',function () { res.writeHeader(200,{'Content-Type':'text/html'}) res.end('<p>Content-Type:' + req.headers['content-type'] + '</p>' + '<p>Date:</p><pre>' + body + '</pre>'); }); } }).listen(3000);
我們監(jiān)聽了data 和 end 事件,創(chuàng)建了一個body 自出穿用來接收數(shù)據(jù)塊,僅當(dāng)end 事件觸發(fā)時, 我們就知道數(shù)據(jù)接收完全了
之所以可以這樣逐塊接收數(shù)據(jù),因為node允許在數(shù)據(jù)到達(dá)服務(wù)器時就可以對其進(jìn)行處理,因為數(shù)據(jù)是以不同的TCP包到達(dá)服務(wù)器的,這和顯示情況也完全匹配,我們現(xiàn)貨區(qū)一部分?jǐn)?shù)據(jù),然后在某個時刻在獲取其余的數(shù)據(jù)
當(dāng)我們在進(jìn)行搜索的時候,,url中高亮的那部分為
q=<search term>
搜索部分的url和表單內(nèi)容一樣都是經(jīng)過編碼的,也就解釋了為什么Content-Type為urlencoded
-
這部分URL片段又被稱為查詢字符串
- node提供了一個
querystring
的模塊,可以方便的對這類字符串進(jìn)行解析,這樣我們就可以想處理頭信息一樣對其進(jìn)行處理,下面是例子\
- node提供了一個
輸出內(nèi)容
- 如圖所示, querystring模塊講一個字符串解析成一個對象,這個解析處理方式和node解析headers消息的方式類似,node將http請求數(shù)據(jù)中得headers信息從字符串解析成一個方便處理的headers對象
整合
- 現(xiàn)在我們要解析發(fā)送來的數(shù)據(jù)并展示出來
- 這里我們用
querystring
parse
方法去解析
const http = require('http');
const qs = require('querystring');
http.createServer(function (req, res) {
if ('/' == req.url) {
res.writeHeader(200, {'Content-Type': 'text/html'});
res.end([
'<form method="post" action="/url">',
'<h1>My form</h1>',
'<fieldset>',
'<label>Personal Information</label>',
'<p>What is your name?</p>',
'<input type="text" name="name">',
'<p><button>Submit</button></p>',
'</form>'
].join(''));
} else if ('/url' == req.url && 'POST' == req.method) {
let body = '';
req.on('data',function (chunk) {
body += chunk;
});
req.on('end',function () {
res.writeHeader(200,{'Content-Type':'text/html'})
res.end('<p>Your name is <b>'+ qs.parse(body).name+'</b></p>');
});
}
}).listen(3000);
- 效果
讓程序更健壯
- 這里有一個問題,如果URL沒有匹配到任何判斷條件怎么辦
- 解決這個問題我們可以在服務(wù)器不知道怎么處理該請求的時候,發(fā)送404給客戶度阿女
- 還有別的解決辦法 但是這里我們采用書上說的方法來解決
const http = require('http');
const qs = require('querystring');
http.createServer(function (req, res) {
if ('/' == req.url) {
res.writeHeader(200, {'Content-Type': 'text/html'});
res.end([
'<form method="post" action="/url">',
'<h1>My form</h1>',
'<fieldset>',
'<label>Personal Information</label>',
'<p>What is your name?</p>',
'<input type="text" name="name">',
'<p><button>Submit</button></p>',
'</form>'
].join(''));
} else if ('/url' == req.url && 'POST' == req.method) {
let body = '';
req.on('data',function (chunk) {
body += chunk;
});
req.on('end',function () {
res.writeHeader(200,{'Content-Type':'text/html'})
res.end('<p>Your name is <b>'+ qs.parse(body).name+'</b></p>');
});
} else {
res.writeHeader(404);
res.end('Not found')
}
}).listen(3000);
- 效果