AppCan 中的AJAX通讯实践

手机应用开发必不可少的就是与网络进行交互。常见的与网络交互都是通过http或https请求方式。这两种方式在以浏览器引擎为核心的Appcan平台中,都是支持的。为了减少数据大小,建议在与网络数据传输时采用json数据格式。
在浏览器中,用异步方式(Ajax)在A网站访问B网站的接口,这种行为被认为是不安全的。为什么呢?想象一个场景:通过Ajax异步请求别的网站接口,返回一个字符串,字符串内容为”<script>//dosomething</script>”,那么这个数据内容就危险了,浏览器会执行<script>标签里面的js代码。这种方式就是所谓的”跨域访问”。这种限制是浏览器做的,其实请求数据已经返回回来。
那么,如何解决跨域访问问题呢,可有几种解决方式
利用第三方网站,比如委托给google网站,google提供了一套跨域访问的js库。
Jquery的$.getJSON方法,这种需要返回数据格式为json格式
在返回头的content-type中设置为application/json
利用Appcan的Native模式开发的widget,也是属于跨域访问的范畴,因此,也会碰到上述情况,这里介绍两种Appcan中的解决方案:
一、Jquery的$.getJSON(url,function(data){});第一个参数是url获取数据地址,第二个参数成功取得数据时调用;
其中,url中必须带有jsoncallback参数,参数值为”?”,Jquery会在请求时替换为一个随机的唯一数:
http://xxxx.php?jsoncallback=?&name1=value1&name2=value2
用$.getJSON时,数据的返回格式要是xxx({“a”:”1″,”b”:”2″})
例如:
xxx({“status”:”true”,”listData”:[{“id”:”261803″,”title”:”虚拟投影键盘”,”name”:”前沿科技”,”summary”:”这款虚拟投影键盘设计独特,每一个敲击都不会相互干扰,可以同时接受。”},{“id”:”261994″,”title”:”科学家发现”最大黑洞””,”name”:”环球快递”,”summary”:”美国加州大学伯克利分校的天文学家尼古拉斯•麦克康纳尔和他的同事发现了两个目前已知最大的黑洞。”}}]})
注意:需验证{“a”:”1″,”b”:”2″}json格式的正确性,可在jsonlint.com网站上验证,如果格式不合法将获取不到数据
 
服务器端需要返回
echo  $[“jsoncallback”].”(“.json_encode($data).”)”; $data为PHP数组
 
二、Appcan封装的uexXmlHttpMgr对象方法如下:
uexXmlHttpMgr.open(String inXmlHttpID, String inMethods, String inUrl);第一个参数:

inXmlHttpID:异步请求操作ID;必须值。(随机不重复)

第二个参数:

inMethods:异步请求类型;(get,post)

第三个参数:

inUrl:异步请求地址;
通过uexXmlHttpMgr.onData函数获取值。
uexXmlHttpMgr.onData(inOpCode,inResult)
inOpCode:操作ID,由发起请求时传入的值,随机不重复;
inResult:服务器返回的任意数据;String类型。
使用方式:

function xmlHttp (){
             var url = document .getElementById ( “add”). value ;
             uexXmlHttpMgr .open (1 , “GET” , url ,“” );
             uexXmlHttpMgr .send (1 );
       }
       function httpSuccess (opid ,status ,result ){
             if (status ==1 ){
             uexXmlHttpMgr .close (1 );
             document .getElementById ( “adre”). value   = result ;
          }
       }

       window .uexOnload = function (){
             uexXmlHttpMgr .onData = httpSuccess ;
             uexWidgetOne .cbError = function( opCode , errorCode , errorInfo ){
                   alert (“errorCode:”   errorCode   “\nerrorInfo:”   errorInfo );
             }
       }
< div data-role =”header  class =” ui-header ui-bar-b ui-header-fixed ui-bar-glass >

< h1 class =”ui-title  tabindex =” 0 role =” heading aria-level=” 1 >
跨域异步请求
</ h1>
</ div>

< div id=” page_5 “ class =”ui-page ui-body-c ui-page-active  tabindex =” 0 >
< div class =”ui-content ui-body-c ui-fixed-top ui-fixed-bottom m-bottom  >
< label for =”text-6  class =” ui-input-text  >请求内容: </ label>
< textarea placeholder =”http://192.168.10.109/phdmyadmin/test.php?func=show    name =”textarea-2  id =” add class=” ui-input-text ui-body-null ui-btn-corner-all ui-shadow-inset ui-btn-d >http://192.168.10.109/phdmyadmin/test.php?func=show </ textarea>
< label for =”text-6  class =” ui-input-text  >请求结果: </ label>
< textarea placeholder =””  name =”textarea-3  id =” adre class =”ui-input-text ui-body-null ui-btn-corner-all ui-shadow-inset ui-btn-d ></textarea >
< div data-role =”button  class =” ui-btn-corner-all ui-btn  ui-btn-e  ui-shadow onclick =xmlHttp( )> < span class =” ui-btn-inner ui-btn-corner-all > <span class=” ui-btn-text “> 发送请求 </span > </ span></ div >

</ div>
</ div>

该方法返回数据只要是正确的json格式就可以;

 
<script>
       /*
       * 跨域异步post请求
       * arguments[0]请求的ID
       * arguments[1]请求php文件中的方法名
       * arguments[2]需要传输的POST键值对像
       */
       function xmlHttp()
       {
             var id    = arguments[0 ] ? arguments [0]: “0”;//真机环境下需要数字作为ID
             var func  = arguments [1] ? arguments[1 ]:“show”;
             var url     = “http://192.168.10.109/phpmyadmin/test.php?func=”  func ;//一定要加HTTP://
             uexXmlHttpMgr.open(id, “POST”, url,“” );
             if(arguments [2])
             {
                   var postKey = “”;
                   var postValue =“” ;
                   for(var key in arguments[2 ])
                   {
                         postKey = key ;
                         postValue = arguments [2][ key];
                         uexXmlHttpMgr.setPostData (id ,“0”, postKey,postValue );//post参数
                   }
             }
             uexXmlHttpMgr.send(id);
             //alert(“发送请求”)
       }
       /*
       * 查询
       */
       function httpSuccess (opid ,status ,result )
       {
             if(status == -1)
             {
                   //alert(“传输失败” )
             }
             if(status == 0)
             {
                   //alert(“正在传输”)
             }
             if(status == 1)
             {
                   //alert(“传输完成”)
                   uexXmlHttpMgr.close(opid);
                   var test = “<input type=”text” id=”content_add”>”
                                “<input type=”button” value=”添加” onclick=”insertItem()”>”;
                   var tmpl = “<div>”
                                “<input type=”text” id=”content_${index:}” value=”${content}”>”
                                “<input type=”button” value=”修改” onclick=”saveItem(${id},${index:})”>”
                                “<input type=”button” value=”删除” onclick=”deleteItem(${id},${id})”>”
                                “</div>”;         
                   var json = eval (result );
                  
                   test  = zy_tmpl (tmpl ,json ,zy_tmpl_count (json ));
                   $( “#content”).html(test);
             }
       }
       /*
       * 修改
       */
       function saveItem ()
       {
             var id = arguments [0];
             var input = $ (“#content_”  arguments[1 ]);
             var content =  input.val();
      
             xmlHttp(“1” ,“save”,{ “id”:id ,“content”: content})
       }
       /*
       * 添加
       */
       function insertItem ()
       {
             var input = $ (“#content_add”);
             var content = var  input.val();
             xmlHttp(“2” ,“insert”,{ “content”:var content })
       }
       /*
       * 删除
       */
       function deleteItem ()
       {
             var id = arguments [0];
             xmlHttp(“3” ,“delete”,{ “id”:id })
       }
       window.uexOnload = function()
       {
             uexXmlHttpMgr.onData = httpSuccess ;//请求数据成功后的回调函数
            
            
   }
</script>
<input class=”btn  type =”button value=” 开始 onclick=”xmlHttp() >
服务端PHP文件

<?php
$cfg_dbhost = “localhost”;
$cfg_dbname = “sitrust”;
$cfg_dbuser = “root”;
$cfg_dbpwd = “”;

$conn = mysql_connect($cfg_dbhost, $cfg_dbuser, $cfg_dbpwd) or die (“不能连接数据库服务器: ” . mysql_error());
mysql_select_db($cfg_dbname, $conn) or die (“不能选择数据库: ” . mysql_error());
mysql_query(“set names utf8”);
/*
**执行$_GET[“func”])传入的方法
*/
if(!empty($_GET[“func”]))
{
 $func = $_GET[“func”];
 $func();
}
/*
**查询
*/
function show()
{
 Global $conn;
 $sql = “select * from `test`”;
 $result = mysql_query($sql,$conn);
 while( $row = mysql_fetch_array($result) )
 {
  $content[] = $row;
 }
  //json数据返回客户端
  echo json_encode($content);
}
/*
**修改
*/
function save()
{
 Global $conn;
 $id = $_POST[“id”];
 $content = $_POST[“content”];
 $sql = “UPDATE `sitrust`.`test` SET `content` = “”.$content.”” WHERE `test`.`id` =”.$id;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}
/*
**删除
*/
function delete()
{
 Global $conn;
 $id = $_POST[“id”];
 $sql = “DELETE FROM `sitrust`.`test` WHERE `test`.`id` = “.$id;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}
/*
**添加
*/
function insert()
{
 Global $conn;
 $content = $_POST[“content”];
 $sql = “INSERT INTO `sitrust`.`test` (`content` ) VALUES (“”.$content.””);”;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}