關(guān)于Lua模塊進(jìn)行Web開發(fā)常見問題解答
關(guān)于Lua模塊進(jìn)行Web開發(fā)常見問題解答是本文要介紹的內(nèi)容,主要是通過LUA web開發(fā)中所提出的問題,邊解決邊學(xué)習(xí),具體內(nèi)容來看本文詳解。
如何獲取HTTP請(qǐng)求頭
直接在 ngx_lua 中訪問 NginX 內(nèi)置變量 ngx.var.http_HEADER 即可獲得請(qǐng)求頭 HEADER 的內(nèi)容。對(duì)于常見的特殊頭(Content-Type、Cookie 等),NginX 還使用了特殊的變量來獨(dú)立保存,例如“Content-Type”頭可以通過 ngx.var.content_type 變量取得。
如何獲取GET參數(shù)
在 ngx_lua 中訪問 NginX 內(nèi)置變量 ngx.var.arg_PARAMETER 即可獲得GET參數(shù)PARAMETER的內(nèi)容。
如何獲取POST請(qǐng)求體數(shù)據(jù)
要獲得完整的POST請(qǐng)求體數(shù)據(jù),可以訪問 NginX 內(nèi)置變量 ngx.var.request_body(注意:由于 NginX 默認(rèn)在處理請(qǐng)求前不自動(dòng)讀取 request body,所以目前必須顯式借助 form-input-nginx 模塊才能從該變量得到請(qǐng)求體,否則該變量?jī)?nèi)容始終為空!)。如果想獲取 POST 方式提交的表單參數(shù),還可以借助 form-input-nginx 模塊省去解析過程。例如:
Nginx代碼
- location /form {
- set_form_input $name;
- content_by_lua '
- local name = ngx.var.name or "";
- local say = ngx.say
- say("My name is: ", name)
- ';
- }
- location /form {
- set_form_input $name;
- content_by_lua '
- local name = ngx.var.name or "";
- local say = ngx.say
- say("My name is: ", name)
- ';
- }
如何設(shè)置/獲取HTTP響應(yīng)頭
我們已經(jīng)設(shè)計(jì)了對(duì)應(yīng)的API接口,近期即會(huì)予以實(shí)現(xiàn)。
如何使用 Lua 外部模塊
通過 require 引用即可,和在普通的 Lua 代碼里一樣。需要注意的一點(diǎn)是,通過 require 引用外部模塊一般有 2 種寫法。老的寫法是:
Lua代碼
- require("xxx")
- require("xxx")
這樣會(huì)將模塊命名空間表直接導(dǎo)入當(dāng)前全局環(huán)境內(nèi);而新的寫法是:
Lua代碼
- local xxx = require("xxx")
- local xxx = require("xxx")
這樣的寫法將模塊命名空間表緩存在同名局部變量中,訪問更快,也不會(huì)污染當(dāng)前全局環(huán)境。但最重要的一點(diǎn)是:老的寫法在 ngx_lua 中會(huì)出現(xiàn)模塊導(dǎo)入后無法訪問的現(xiàn)象!這是由 ngx_lua 實(shí)現(xiàn)原理決定的。
ngx_lua 使用每請(qǐng)求一個(gè) coroutine 的方式運(yùn)行用戶代碼,coroutine 的全局環(huán)境是重新關(guān)聯(lián)的,因此用戶代碼相當(dāng)于運(yùn)行在一個(gè)沙盒中,請(qǐng)求處理結(jié)束后用戶代碼產(chǎn)生的所有全局環(huán)境修改都會(huì)被舍棄,避免多個(gè)請(qǐng)求之間產(chǎn)生交叉影響,也降低了因?yàn)E用全局環(huán)境產(chǎn)生內(nèi)存泄漏的風(fēng)險(xiǎn)。而 require 利用了全局共享的 package.loaded 表緩存已載入模塊的數(shù)據(jù),以達(dá)到避免重復(fù)加載模塊的目的。很明顯,這種結(jié)構(gòu)必然會(huì)使首個(gè)請(qǐng)求中通過 require 注入全局環(huán)境的模塊命名空間表在后續(xù)請(qǐng)求中無法訪問,因?yàn)楹罄m(xù)請(qǐng)求中 package.loaded 表內(nèi)已經(jīng)有之前加載模塊的數(shù)據(jù),故 require 不會(huì)再次將命名空間表注入當(dāng)前全局環(huán)境,使得以后所有依賴于模塊的操作都失敗。
鑒于這一問題,我們推薦web開發(fā)人員總是使用新的 require 寫法(即使用局部變量緩存模塊表),對(duì)于那些因?yàn)槟撤N原因無法更新 require 寫法的代碼,可以通過在開始處理請(qǐng)求前清空 package.loaded 表中對(duì)應(yīng)模塊數(shù)據(jù)的方式強(qiáng)制加載模塊并注入全局環(huán)境(注意每次都加載模塊可能產(chǎn)生性能瓶頸!),例如:
Lua代碼
- package.loaded.xxx = nil
- require("xxx")
小結(jié):關(guān)于Lua模塊進(jìn)行Web開發(fā)常見問題解答的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對(duì)你有所幫助!