网上关于添加一个uci模块的资料比较多,但定制Luci的资料很少,自己摸索了好几天,找到了一种方法,虽然不是很完美,但可以用,跟大家分享一下。
1.怎么绕开认证
首先备份一下/usr/lib/lua/luci/controller/admin文件夹,省得想改回去的时候已经晚了。
/usr/lib/lua/luci/controller/admin/index.lua 中注释掉以下两句:
--page.sysauth = "root"
--page.sysauth_authenticator = "htmlauth"
这两句和认证相关,注释掉之后认证就不起作用了。
然后,可以看到上面有一句page.target =firstchild(),表示认证之后转向到第一个子节点。Firstchild机制是什么不想仔细研究了,贸然改代价大。把你自己的页面变成firstchild就好了。那么谁是firstchild呢?可以看到admin文件夹下的lua文件都有index函数,index中有entry,entry最后一个参数是个数字,这个数字序号越小,菜单排序就越靠前。所以,你把你自己的lua文件entry的序号改成所有lua文件中最小的就行。我因为需要完全自定义界面,所以删除了admin下的其他页面的lua文件,只保留了index,uci和自己的lua文件。这样,firstchild只能是我的lua中的某条entry了。
这样,就可以绕开认证,直接跳转到自己的页面了。
2.一种页面和后台交互的机制
介绍Luci的页面和后台交互机制的资料也比较少。我根据网上的资料试出一种。首先,controller中的entry比较关键。Entry的形式如下:
entry({"admin","xxx","login"},call("login_process"),nil,nil)
这些参数有很多理解方法,在交互方面可以这样理解:
第一个参数实际是请求的url。第二个参数是对请求的处理。后两个参数可以去网上搜搜,介绍的比较多。
这样一来,后台处理就有了。那么前端如何发起请求呢?前端的页面放在/usr/lib/lua/luci/view下,可参考该文件夹下的其他代码。我没怎么做过web,所以不是很清楚通常做法是什么,找了点资料,发现可以使用xhr发起请求。我主要使用了post方法,poll方法没调好,所以主要给大家介绍post。举个例子:
new XHR().post('/cgi-bin/luci/admin/xxx/login', {usr:username ,pwd:password},
function(xhr) {
console.log(xhr.responseText);
console.log("xhr:"+xhr);
top.location.href= '<%=REQUEST_URI%>'+'admin/xxx/aaa';
});
三个参数,第一个是url,要和controller的entry中的url保持一致。第二个参数是post附带的数据,可以写成那种json格式。第三个参数是回调函数,就是后台处理完成后通过这个函数来传递信息。
具体交互流程如下:
首先,前端页面将数据放在第二个参数,向第一个参数url发起请求。
数据到达后端服务器,在处理函数中可以通过:
local username = luci.http.formvalue("usr")
local password = luci.http.formvalue("pwd")
来接受数据。然后通过
Local rv = {
status ="ok"
msg ="xxxx"
}
luci.http.prepare_content("application/json")
luci.http.write_json(rv)
来向前端回复数据。
回复数据来到前端,在xhr中,要解析可以这样做:
使用xhr.responseText变成字符串,然后使用JSON.parse(xhr.responseText);将字符串解析为json。
如果需要跳转到其他页面可以使用top.location.href= '/cgi-bin/admin/xxx/aaa';
需要注意的是,在调试的时候,修改controller下的lua文件后,直接使用是没有效果的,需要删除/tmp下的以luci-开头的一个文件和一个文件夹。luci-indexcache文件(好像是这个,记不清了),文件夹记不清了,比较容易辨认,在网上搜搜也有说明。删除这两个东西之后,luci会重新加载lua文件,就能把修改体现出来了。