想请教有关于 HTTP parse form 类型之 package 的原理
 发布于 11 年前  作者 grass0916  6811 次预览  最后一次回复是 11 年前  来自 问答 

想请教有关于 HTTP parse form 类型之 package 的原理

一般来说在 submit form 时我们都会使用 application/x-www-form-urlencoded(default)multipart/form-data 这两种 Encryption 为主。于是我就好奇了相关的 package(body-parsernode-formidablemulter 等)是如何解析的,不过我尝试 console 出 req(request)的 headers 却找不到 form 的本体,请问这是 HTTP 本身对于相关资讯会做的加密吗?想请教各位这方面是如何运作的。

以下是我尝试 submit 一 form,其中资讯有 { email: ‘hello’, password: ‘test’ } ,所收到的 req(request)headers。(这是基于 express 底下回传的 req,不晓得是否有被 express 动过手脚)

{ host: 'localhost',
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:35.0) Gecko/20100101 Firefox/35.0',
  accept: '*/*',
  'accept-language': 'en-US,en;q=0.5',
  'accept-encoding': 'gzip, deflate',
  'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  'x-requested-with': 'XMLHttpRequest',
  referer: 'http://localhost/login',
  'content-length': '25',
  cookie: 'jsbin=s%3Aj%3A%7B%22_csrf%22%3A%22EuAqXkQHR0vwM78bU%2BDROZ4B%22%2C%22flash%22%3A%7B%7D%7D.DIpnFp%2BmrfbErEhC3O2UXhx6JWkRutzeBRv0B308pvQ; _node=fd69ab210bd73bb0a5e5c34e0b15b618753315aa142180649818551c30df416b6b5f9eb9edbfa6a942ad6',
  connection: 'keep-alive',
  pragma: 'no-cache',
  'cache-control': 'no-cache' }
10 回复
chinghanho

以 body-parser 來說,解析 req.body 流程大概是這樣:

  1. raw-body 解析最原始 HTTP request 取得 form 的「raw body」,這部分實作太底層我不懂,看看能否有其他人補充?
  2. 用 node.js 的 querystring 模組解析得到的「raw body」,如果有啟用 extended 選項,則是使用 TJ 寫的 qs(已經移轉給 hapi.js 團隊維護),最終都是輸出成可利用的 JSON object。
  3. 然後把 JSON object 寫入到 req.body

done。

DevinXian

建议直接打印req,而不是req.headers;可以使用util.inspect多深入几层。

grass0916

@chinghanho 是的我有開啟 extended,以上的輸出結果就是被轉成 JSON 的 format。不過在 express 搭載的 body-parse 已經使用過 raw-body 後,經過其他過程中將初始 request 做了更動,這樣的話 …(我試試看等等再回報 @@")

grass0916

@DevinXian

详细 request on Gist

Line 3993 可以见到经过 body-parser 解析过的 body: { email: ‘hello’, password: ‘test’ }

不过还是没有在全文中找到相关形成 form 的资讯。

grass0916

@DevinXian 好似不是,换个方式请教您好了,submit 的 form 本体应该是会在 request 中 headers 这点应该没错吧?

chinghanho

@DevinXian Express 中得到的 req 已經是被處理過包裝後的 object,並不是從 HTTP 傳過來的「最原始的」request,所以這裏是看不到「request 原始形體」的。

HTTP request 的結構如何我沒有深入研究過,按照我的理解,submit form 本體不是放在 header 裡。我翻了一下網路上的資料,HTTP request 應該跟 HTML 有點像,分為 header 跟 body 兩個部分。

希望有知道的人可以解說一下。:D

grass0916

@chinghanho 謝謝 HanHo,我在你附上的資料前一章節的 3.6.1 Chunked Transfer Coding 見道。Chunked-Body 似乎就是會存放 submit 出去 的 form 本體的區域,不過不確定是不是被 express 做完 parsing 後就將其移除了,亦或是它本身就不存在於 request 中(我個人認為不大可能,像我最前面提到的 node-formidable 它只需要傳入 req 就可以自動解析 multipart form,太神妙了)。 Q_Q

grass0916

蠻有趣的,我花一些時機看看這本好了。 HTTP: The Definitive Guide http://it-ebooks.info/book/1401/

chinghanho

@grass0916

OK,看來我錯的,剛去掃了下 node-formidable 的 code,我想關鍵在這一段吧,也就是你貼在 Gist 上的這個函示:

req.on('data', function(buffer) {
  console.log(buffer)
})

資料就在那個 buffer 裡。:)

node-formidable 會判斷不同的 Content-Type 使用不同的 parser 去解析這個 buffer,以 urlencoded 這個類型為例,他會使用這個檔案的程式去解析。