由于最近的一項工作中有需要使用 Node.js 來編寫一個 HTTP 工具, 其中就有包括 GET/POST 參數(shù)的處理, 也遇到了一些小問題, 所以順便就寫下來, 作為一個小知識普及. 嗯, 就是醬紫, 不要問我隔壁老王是誰.
首先我們先了解下 HTTP GET 與 HTTP POST 兩者有什么不同
它們都是 HTTP 中的一種發(fā)送請求方式. 并不是廣義上的一個取, 一個發(fā). 所以不要被名字所誤導(dǎo)了.
GET 與 POST 方式常常被提到的區(qū)別就有: 1. 安全性, 2. 傳輸數(shù)據(jù)大小, 3. 傳輸數(shù)據(jù)時載體不同.
具體可以在 w3schools 中看到具體說明.
但是在這里我們僅僅來討論它們兩者數(shù)據(jù)的傳輸載體不同, 更多內(nèi)容可以查閱維基老頭給我們的說明. 點(diǎn)我拜訪維基老頭
POST
先說說 POST 方式, 它是將數(shù)據(jù)各字段及內(nèi)容添加到請求的 HEADER 中去, 然后隨著請求發(fā)送到服務(wù)器端, 這個過程是不可見的;
GET
GET 方式, 是將參數(shù)數(shù)據(jù)隊列添加到 URL 中去的, 所以我們常??梢钥吹?URL 中使用 ‘&’ 符號來拼接各種鍵值對應(yīng)的參數(shù).
如: http://localhost:1337/index?name=root&password=1234
但是這種方式就存在安全問題了, 具體在這就不做討論了.
前邊一堆廢話過去了, 是時候進(jìn)入主題了.
在 Node.js 的官網(wǎng)上我們可以看到, 官方給出了一個簡單的 HTTP Server 程序例子.
這部分以官網(wǎng)上的代碼為例, 來理解 Node.js 中 GET/POST 參數(shù)的獲取.
var http = require('http');http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');
在這個例子中, 假如我們需要獲取 GET/POST 方式傳遞過來的參數(shù), 是無法直接得到的, 需要對 request 對象進(jìn)行處理, 才可以得到我們想要的參數(shù).
參數(shù)都是以鍵值方式拼接在請求的 URL 當(dāng)中的, 所以我們可以通過解析 URL 來獲得參數(shù).
我們可以通過 Node.js 內(nèi)建的 url 庫來解析 GET 請求過來的 URL.
var url = require('url');
然后調(diào)用 url.parse 函數(shù).
var params = url.parse(request.url, true).query; // params 即為我們需要的參數(shù)
然后打開瀏覽器, 嘗試請求我們的 HTTP Server.
如: http://localhost:1337/index?username=root&action=test , 在 url 中附帶參數(shù).
然后打印我們的 params, 即可看到如下圖的內(nèi)容.
完整的代碼如下:
var http = require('http');var url = require('url');http.createServer(function (request, response) { var params = url.parse(request.url, true).query; console.log(params); response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');
由于 POST 方式傳遞的參數(shù)并不會顯示在 URL 中, 所以上邊的方式就不可行了, 那么我們就要換一種方式了.
前邊我們已經(jīng)知道了, POST 方式, 它會將參數(shù)數(shù)據(jù)添加到請求的 HEADER 中發(fā)送到服務(wù)端, 所以, 我們需要去解析 HEADER 中的數(shù)據(jù)來獲取 POST 請求發(fā)送過來的參數(shù).
這里我們就需要使用 ‘querystring’ 這個庫了, 用來處理 response 對象的數(shù)據(jù), 完整代碼如下.
var http = require('http');var querystring = require('querystring');http.createServer(function (request, response) { request.setEncoding('utf-8'); var postData = ''; // 注冊監(jiān)聽, 接收數(shù)據(jù)塊 request.addListener("data", function (postDataChunk) { postData += postDataChunk; }); // 數(shù)據(jù)接收完畢, 執(zhí)行回調(diào)函數(shù) request.addListener("end", function () { var params = querystring.parse(postData); //解析 HEADER 中的數(shù)據(jù) console.log(params); response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); });}).listen(1337, '127.0.0.1');
由于 POST 傳輸數(shù)據(jù)的量相較于 GET 方式較大, 所以這里并不能直接得到數(shù)據(jù), 而是通過添加兩個監(jiān)聽器, 分別處理數(shù)據(jù)接入過程以及數(shù)據(jù)接入完兩個狀態(tài).
但是, 這并不是最理想的. 當(dāng)你是通過 ‘FORM-DATA’ 方式發(fā)送請求的話, 我們接收到的結(jié)果并不是我們想象中的樣子. 比如我通過 POSTMAN 去發(fā)送一個 ‘FORM-DATA’, 其中包含了 ‘name’ 及 ‘password’ 兩個字段的數(shù)據(jù). 我們解析出來的結(jié)果是如下圖:
它雖然是一個 JS 對象, 但是它的內(nèi)容于我們而言幾乎是不可用的, 盡管依稀可以見到 ‘name’ 跟 ‘password’ 兩個字段, 但是處理起來還是比較費(fèi)勁.
而當(dāng)我們在發(fā)送數(shù)據(jù)時, 是通過發(fā)送 ‘a(chǎn)pplication/json’ 類型的數(shù)據(jù), 如下圖 POSTMAN 的使用.
然后我們就能順利看到我們傳遞過來的參數(shù)了.
Express 是 Node 服務(wù)端里我們比較常見的 Web 框架. Express.js 框架有較為完善的封裝, 可以讓我們直接獲取 GET/POST 方式傳遞過來的參數(shù).
在 Express.js 框架中, 我們每個請求都會有一個 Request 對象, 通過查閱 API 我們發(fā)現(xiàn), Request 對象有一個 params 屬性, 我們發(fā)送請求時所附帶的參數(shù)數(shù)據(jù)都被保存在其中, 我們可以直接調(diào)用.
如: request.params['name']
或者是 request.params.name
.
詳見 Express.js 上 Request 對象的 API: http://expressjs.com/4x/api.html#req.params
理解 GET/POST 兩種請求的參數(shù)傳遞方式.
GET 的參數(shù)都是附加于 URL 中的, 而 POST 的參數(shù)是添加在 Body 中的.
但是, 這不是必須的, 我們一樣可以在 GET 請求時, 設(shè)置參數(shù)在 Body 中, 而 POST 請求時, 將參數(shù)放置在 URL 中. 但是因為一些考慮, 才有上邊的結(jié)果.
比如, URL 帶有參數(shù)的 GET 請求, 我們可以將其保存在書簽中, 下次通過地址訪問一樣的內(nèi)容.
而對于 POST 請求, 它不會被瀏覽器的歷史記錄了, 且不可保存在書簽中, 于是乎, 有了一點(diǎn)點(diǎn)安全性, 但只是一點(diǎn)點(diǎn), 對于有心人, 一樣可以記錄請求, 以及獲取參數(shù).
打完收工. 另外還有一篇文章, 可以一看 GET和POST有什么區(qū)別? 及為什么網(wǎng)上的多數(shù)答案都是錯的
聯(lián)系客服