Ajax的好处就是可以实现无刷新动态更新。后台配合Mod_python程序,使后台处理变得非常高效简洁。【index.html】
<HTML> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Ajax测试页面</title> <script language="JavaScript"> function checkForm(){ var messageDiv = document.getElementById("msgDiv"); var product = document.getElementById("product"); var pvalue = product.options[product.selectedIndex].value; var svalue = document.getElementById("sn").value; if(svalue == ""){ messageDiv.style.color = "Red"; messageDiv.innerHTML = "请输入序列号!"; return false; } //alert(svalue); //var par = "pv=" + pvalue + "&sv=" + svalue var par = "sv=" + svalue if (pvalue == 0){ sendRequest("mypython/pro1", par); return true; }else{ messageDiv.innerHTML = "抱歉,该产品信息尚未入库!"; return false; } } function sendRequest(url, par){ //注意,这里定义的是一个局部变量,即每调用一次都创建一个新的XMLHttpRequest对象,即发送一个新的请求 var xmlHttp = false; if(window.XMLHttpRequest){ //for mozilla xmlHttp = new XMLHttpRequest(); }else if(window.ActiveXObject){//for IE try{ xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ } } } xmlHttp.open("POST",url,true); xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4) { if(xmlHttp.status == 200) { //alert("123456"); var mdiv = document.getElementById("msgDiv"); mdiv.style.color = "Red"; mdiv.innerHTML = xmlHttp.responseText; }else alert("Error!" + " Status code is: " + xmlHttp.status + " Status text is: " + xmlHttp.statusText); } } xmlHttp.setRequestHeader("Content-length", par.length); xmlHttp.setRequestHeader("Content-Type","text/xml"); //xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8"); xmlHttp.send(par); // 名=值&名=值&名=值... } </script> </head> <Body style="background-color:#e0f4df"> <br/> <br/> <br/> <br/> <br/> <div align="center"> <!--为什么不能用Form表单,因为表单必需有返回,会导致当前页面闪烁或是跳转 --> <!--form name="myform" id="myform" action="" method="POST" onsubmit="return checkForm()"--> <table border="1px" cellspacing="0px" cellpadding="0px"> <tr><td>请选择产品的型号:</td><td> <select id="product"> <option value ="0">3D打印机</option> <option value ="1">3D扫描仪</option> </select> </td></tr> <tr><td>请输入产品序列号:</td><td> <input id="sn" type="text" size="14" value="" /> </td></tr> <tr><td colspan="2" align="center"> <button onClick="return checkForm()">点击查询</button> </table> <!--/form --> </div> <br/> <div align="center" id="msgDiv"></div> </Body> </HTML>
然后就是后台的mod_python程序:【mypython.py】
#!/usr/bin/python # -*-coding:UTF-8-*- from mod_python import apache, util from MySQLdb import * def pro1(req, sv): svalue = sv req.write(svalue)
只要保证前台Ajax所Post的参数名称 与 mod_python 指定的参数名称一致(如“sv”),就可以获取前台传递过来的参数了。
该方法可以在Firefox上完美的工作,但在其它浏览器则返回501:method not implemented 错误信息。
搜索了很久发现是由于Ajax请求发送的标准数据类型:
xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8")
导致的。好像是mod_python/util.py 无法正确解析,应该是mod_python的一个bug.
最终没有找到好的解决方法,最后只能选择一个替代方案:Form + iFrame 的方式来实现无刷新提交。【index.html】
<HTML> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>iFrame测试页面</title> <script language="JavaScript"> function checkForm(){ var messageDiv = document.getElementById("msgDiv"); var product = document.getElementById("product"); var pvalue = product.options[product.selectedIndex].value; var svalue = document.getElementById("sn").value; if(svalue == ""){ messageDiv.style.color = "Red"; messageDiv.innerHTML = "请输入序列号!"; return false; } if (pvalue == 0){ //R2 return true; }else{ messageDiv.innerHTML = "抱歉,该产品信息尚未入库!"; return false; } } function callback(msg){ var mdiv = document.getElementById("msgDiv"); mdiv.innerHTML = msg; } </script> </head> <Body style="background-color:#e0f4df"> <br/> <br/> <br/> <br/> <br/> <div align="center"> <!--为什么不能用Form表单,因为表单必需有返回,会导致当前页面闪烁或是跳转 --> <form name="myform" id="myform" action="mypython/pro1" method="POST" target="i_frame" onsubmit="return checkForm()"> <table border="1px" cellspacing="0px" cellpadding="0px"> <tr><td>请选择产品的型号:</td><td> <select name="pv" id="product"> <option value ="0">3D打印机</option> <option value ="1">3D扫描仪</option> </select> </td></tr> <tr><td>请输入产品序列号:</td><td> <input name="sv" id="sn" type="text" size="14" value="" /> </td></tr> <tr><td colspan="2" align="center"> <input type="submit" value="点击查询"></td></tr> </table> </form> </div> <br/> <div align="center" id="msgDiv"></div> <iframe name="i_frame" width="1px" height="1px" style="display:none" ></iframe> </Body> </HTML>
注意,必需定义一个iframe,但width与height不能设置为0px 。然后form里面的target属性必需指定成iframe的name值(如“sv”)。Form里面需要提交到后台的节点需设置name属性。
后台mod_python程序:【mypython.py】
#!/usr/bin/python # -*-coding:UTF-8-*- from mod_python import apache, util from MySQLdb import * def pro1(req, sv): svalue = str(sv) return "<html><body onload="javacript: parent.callback('" + svalue + "')"></body></html>"
必需使用return返回数据前台才能收到。
可以看到返回的是一段简单的HTML代码,该代码会返回到前台的iFrame里面。且一加载就会运行一句javascript代码。该javascript代码会调用前台父页面的callback()函数把返回的信息输出到指定的DIV之中。
该方法可以实现完美的浏览器兼容。