HTML Javascript CGI
最近工作需要实现一个web 服务器。用来显示设备参数以及修改参数等简单的功能。由于是嵌入式设备,所以选择了一些小型的web 服务器。
shttpd:
小型嵌入式web服务器,可以使用C和C++来实现网页。不过完全由C语言来实现网页代码结构非常乱,后期维护修改肯定是灾难。还是用HTML语言来实现网页比较好。
HTML:
一个html页面通常需要包括 html、css、javascript。以一个登陆界面为例:
<html>
<head>
<title>StarDCU Web</title>
<style>
.login{
position: absolute;
width: 30%;
height: 50%;
border:1px solid #d3d3d3;
margin:0 auto;
left:50%;top:50%;
margin-left:-15%;margin-top:-15%;
#background: url(timg.jpg) no-repeat center;
background-color: #FAFAFA;
}
.login_form{
border:1px solid #d3d3d3;
position:relative;
height: 15%;
width: 90%;
top: 5%;
left:5%
}
.login_edit{
position:relative;
width: 90%;
height:75%;
top:12%;
border:0px;
outline:none;
font-size:20px;font-weight:normal;
color:#d3d3d3;
background-color: #FAFAFA;
}
.login_btn{
position:relative;
width: 35%;
height: 70%;
top:20%;
}
.login_msg{
position:relative;
top:20%;
width:100%;
border:0px;
color:red;
background-color: #FAFAFA;
}
</style>
</head>
<body style="text-align:center;">
<div class="login">
<form class="login_form" style="border:0px;">
<h2 style="text-align:left;color:#A3A3A3">Login</h2>
</form>
<form class="login_form" id="user_form">
<input type="text" id="user" class="login_edit" placeholder="User name"></input>
</form>
<form class="login_form">
<input type="password" id="pass" class="login_edit" placeholder="Password"></input>
</form>
<form class="login_form" style="border:0px;">
<input type="button" onclick="getConfig(0)" id="login_ok" class="login_btn" value="Login"></input>
</form>
<form class="login_form" style="border:0px;">
<input type="text" id="msg" class="login_msg" disabled="true"></input>
</form>
</div>
<script type="text/javascript" src="file.js"></script>
<script>
var timer;
function getConfig(index)
{
var user = document.getElementById("user").value;
if(user.length === 0)
{
document.getElementById("msg").value = "user name is null...";
return;
}
var pass = document.getElementById("pass").value;
if(pass.length === 0)
{
document.getElementById("msg").value = "password is null...";
return;
}
timer = window.setTimeout("timeout()",2000);
httpGet(index, login);
}
function timeout()
{
login("");
}
function login(string){
window.clearTimeout(timer);
var user = document.getElementById("user").value;
var pass = document.getElementById("pass").value;
if(string.length === 0)
{
document.getElementById("msg").value = "login timeout...";
return;
}
if(getQueryStringByName(string,"user_name") !== user)
{
document.getElementById("msg").value = "user name is incorrect...";
return ;
}
if(getQueryStringByName(string,"user_pass") !== pass)
{
document.getElementById("msg").value = "password is incorrect...";
return ;
}
//set session value
sessionStorage.setItem("login", 1);
//jump page
self.location='dcu.html';
}
document.onkeydown=function(event){
if(event.keyCode==13){
document.getElementById("login_ok").click();
}
};
</script>
</body>
</html>
style即CSS代码,用来定义界面样式。通常的方法是将这些样式定义保存在文件中,方便所有页面调用。调用方法class=”name”。
javascript 实现页面逻辑,可以做很多后台处理的操作。
Javascript
第一次试着实现web服务器,页面部分比较简单(当然只是比较简陋的界面)。比较麻烦的是我需要从其他程序获取设备信息,换言之就是要与其他程序进行数据交换。那么网页的数据怎么传递和获取呢。又是传递给谁呢?
网上很多说用ajax,Ajax是一种一种创建交互式网页应用的网页开发技术。具体就是XMLHttpRequest。
页面交互主要就是GET/POST两个请求
function httpGet(index, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "./config.cgi?"+index, true );
xmlHttp.setRequestHeader("If-Modified-Since","0");
xmlHttp.send();
xmlHttp.onreadystatechange=function()
{
//get request ready
if (xmlHttp.readyState==4 && xmlHttp.status==200)
{
keyList.length = 0;
valList.length = 0;
callback(xmlHttp.responseText);
}
}
}
function xmlHttpPost(str)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "POST", "./config.cgi", true );
// xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("If-Modified-Since","0");
xmlHttp.send(str);
xmlHttp.onreadystatechange=function()
{
//get request ready
if (xmlHttp.readyState==4 && xmlHttp.status==200)
{
//alert(xmlHttp.responseText);
}
}
}
通过XMLHttpRequest很容易像cgi程序发送请求。还有其他方式,比如建立虚拟form的方式来提交
function post(PARAMS) {
var iframe = document.createElement("iframe");
iframe.style.display = "none";
var form = document.createElement("form");
form.action = "./config.cgi";
form.method = "post";
form.style.display = "none";
form.target = "iframe";
for(var i=0; i<PARAMS.length; i+=2)
{
var opt = document.createElement("input");
opt.name = PARAMS[i];
opt.value = PARAMS[i+1];
form.appendChild(opt);
}
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
不过这种方式我没有使用,因为它在提交后会跳转页面。Javascript语法不难理解,用起来甚至感觉很方便,回调函数参数传递等。
CGI
CGI 通用网关接口,通过环境变量来与html进行交互。主要的环境变量有
SERVER_NAME:运行CGI序为机器名或IP地址。
SERVER_INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。
SERVER_PROTOCOL:通信协议,应当是HTTP/1.0。
SERVER_PORT:TCP端口,一般说来web端口是80。
HTTP_ACCEPT:HTTP定义的浏览器能够接受的数据类型。
HTTP_REFERER:发送表单的文件URL。(并非所有的浏览器都传送这一变量)
HTTP_USER-AGENT:发送表单的浏览的有关信息。
GETWAY_INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。
PATH_TRANSLATED:PATH_INFO中包含的实际路径名。
PATH_INFO:浏览器用GET方式发送数据时的附加路径。
SCRIPT_NAME:CGI程序的路径名。
QUERY_STRING:表单输入的数据,URL中问号后的内容。
REMOTE_HOST:发送程序的主机名,不能确定该值。
REMOTE_ADDR:发送程序的机器的IP地址。
REMOTE_USER:发送程序的人名。
CONTENT_TYPE:POST发送,一般为application/xwww-form-urlencoded。
CONTENT_LENGTH:POST方法输入的数据的字节数。
CGI程序会在GET/POST请求发送时运行,通过读取环境变量来获取传递的信息。然后在将结果返还给javascript。
通过调用cgic库来实现自己的cgi程序。cgic实现了main函数,获取了环境变量的信息,并将对应的数据存储在变量中方便程序获取。
在cgi程序中可以完全按你喜欢的方式获取数据。但是有一点需要注意,CGI程序会在任意发送GET/POST的时候被调用。运行完成后就会退出,CGI会在退出后将stdout的信息传递给Javascript。所以CGI程序的运行时间应尽量简短。如果运行时间过长,下一次调用时就会出错,从而获取不到数据信息。