AJAX实用教程——模拟google天气预报xml接口

         这个Demo是通过POST方法向服务器请求天气xml,本来也想直接访问google的天气xml接口,但是这也涉及到跨域(跨域知识前一篇有讲解),只能作罢,没办法只好自己用.NET写了一个模拟的服务器。

        

         通过本例,展示了如下技术:

 

         l  利用AJAX向服务器POST请求。

         l  利用javascript解析xml数据。

         l  利用javascript更改html界面显示。

 

         Demo概要说明:

 

         服务器端有一个ashx服务文件,客户端通过AJAX技术向服务文件POST请求信息,如果信息正确,服务文件将读取同目录下的xml文件,返回给客户端。

         客户端index.html为展示页面,调用ajax.js完成AJAX请求,并解析返回的xml在界面上显示。

 

         具体代码:

 

         Html代码(index.html):

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 2 

 3 <html xmlns="http://www.w3.org/1999/xhtml">

 4     <head>

 5         <title>POST方式获取天气信息演示</title>

 6         <script type="text/javascript" language="javascript" src="ajax.js"></script>

 7     </head>

 8     <body>

 9         <div id="frmMain">

10             <ul id="weatherInfo"></ul>

11             <input name="btnGet" value="获取天气信息" onclick="javascript:googleWeather();" type="button" />

12         </div>

13        

14     </body>

15 </html>

         AJAX脚本(ajax.js):

 1 function googleWeather() {

 2     //根据浏览器类型创建不同的XMLHttpRequest对象

 3     var xmlHttp;

 4     if (window.XMLHttpRequest) {

 5         xmlHttp = new XMLHttpRequest();

 6     } else {

 7         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

 8     }

 9 

10     //绑定http请求响应完成之后的回调函数

11     //注意:我是为了方便新人学习才写这么分散的,其实很多东西都可以连着写

12     xmlHttp.onreadystatechange = function () {

13         //判断是否响应完成

14         //readyState == 4 表示响应完成

15         //status == 200 表示请求成功

16         if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

17             //获取服务器端返回的xml格式数据

18             //获取xml格式数据responseXML,获取文本格式数据responseText

19             var xml = xmlHttp.responseXML;

20             //获取xml中的当日天气信息

21             //getElementsByTagName返回的是数组,考虑到xml只有一个current_conditions元素,因此直接取数组第0个元素

22             var currentWeather = xml.getElementsByTagName("current_conditions")[0];

23             //获取当日天气元素

24             var conditionNode = currentWeather.getElementsByTagName("condition")[0];

25             //获取当日天气值。getAttribute()方法可以获取元素的某个属性值。

26             var conditionData = conditionNode.getAttribute("data");

27             //获取当日湿度元素

28             var humidityNode = currentWeather.getElementsByTagName("humidity")[0];

29             //获取当日湿度值

30             var humidityData = humidityNode.getAttribute("data");

31             //获取当日风向元素

32             var wind_conditionNode = currentWeather.getElementsByTagName("wind_condition")[0];

33             //获取当日风向值

34             var wind_conditionData = wind_conditionNode.getAttribute("data");

35             //获取界面上的ul元素

36             var ulNode = document.getElementById("weatherInfo");

37             //将三个值显示在ul中

38             ulNode.innerHTML += "<li>" + conditionData + "</li>";

39             ulNode.innerHTML += "<li>" + humidityData + "</li>";

40             ulNode.innerHTML += "<li>" + wind_conditionData + "</li>";

41         }

42     };

43 

44     //构造请求参数

45     //第一个参数指定为POST方式请求

46     //第二个参数是请求的url地址

47     //第三个参数是指是否异步,true为异步

48     xmlHttp.open("POST", "weather/api.ashx", true);

49     //构造http头,Content-type是个非常重要的头,如果不设置,服务器可能无法解析参数

50     xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

51     //发送请求

52     //post方式方式请求,参数要写在send方法里。get方式直接把参数写在url上即可

53     xmlHttp.send("hl=cn&weather=beijing");

54 }

         服务文件(api.ashx):

 1 <%@ WebHandler Language="C#" Class="api" %>

 2 

 3 using System;

 4 using System.Web;

 5 

 6 public class api : IHttpHandler {

 7     

 8     public void ProcessRequest (HttpContext context) {

 9         //返回数据类型一定要设置正确,text/xml代表返回xml格式的数据

10         context.Response.ContentType = "text/xml";

11 

12         //判断post参数是否正确

13         if (context.Request.Form["hl"] != null && context.Request.Form["hl"].ToString().ToLower() == "cn")

14         {

15             if (context.Request.Form["weather"] != null && context.Request.Form["weather"].ToString().ToLower() == "beijing")

16             {

17                 //参数正确则返回xml格式的天气信息。

18                 //weather.xml文件与该服务文件在同一目录下,天气信息保存在这个文件中

19                 context.Response.WriteFile("weather.xml");

20             }

21         } 

22     }

23  

24     public bool IsReusable {

25         get {

26             return false;

27         }

28     }

29 

30 }

         天气xml文件(weather.xml):

 1 <?xml version="1.0" encoding="utf-8"?>

 2 <xml_api_reply version="1">

 3     <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0">

 4         <forecast_information>

 5             <city data="beijing" />

 6             <postal_code data="beijing" />

 7             <latitude_e6 data="" />

 8             <longitude_e6 data="" />

 9             <forecast_date data="2009-07-31" />

10             <current_date_time data="2009-07-31 16:32:12 +0000" />

11             <unit_system data="SI" />

12         </forecast_information>

13         <current_conditions>

14             <condition data="晴" />

15             <temp_f data="79" />

16             <temp_c data="26" />

17             <humidity data="湿度: 65%" />

18             <icon data="/ig/images/weather/sunny.gif" />

19             <wind_condition data="风向: 东、风速:2 米/秒" />

20         </current_conditions>

21         <forecast_conditions>

22             <day_of_week data="周五" />

23             <low data="16" />

24             <high data="31" />

25             <icon data="/ig/images/weather/chance_of_rain.gif" />

26             <condition data="可能有雨" />

27         </forecast_conditions>

28         <forecast_conditions>

29             <day_of_week data="周六" />

30             <low data="22" />

31             <high data="31" />

32             <icon data="/ig/images/weather/chance_of_storm.gif" />

33             <condition data="可能有暴风雨" />

34         </forecast_conditions>

35         <forecast_conditions>

36             <day_of_week data="周日" />

37             <low data="19" />

38             <high data="29" />

39             <icon data="/ig/images/weather/chance_of_storm.gif" />

40             <condition data="可能有暴风雨" />

41         </forecast_conditions>

42         <forecast_conditions>

43             <day_of_week data="周一" />

44             <low data="23" />

45             <high data="32" />

46             <icon data="/ig/images/weather/chance_of_rain.gif" />

47             <condition data="可能有雨" />

48         </forecast_conditions>

49     </weather>

50 </xml_api_reply>

         代码中注释非常详细,相信读者能够领会整个过程。

 

         补充说明:

 

         在这个Demo中,小菜要着重说下Http协议的头部信息。在js代码中有这样一句话:xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");这个就是设置Http头部信息中的解析类型(Content-type)。

         头部信息包括了很多东西,比如Host、Referer、cookie等,这些信息可以理解为请求的一些参数,用来在服务器端识别。

         头部信息很重要,尤其是以POST方式请求数据时,头部信息未设置或者不正确,很可能出现一些莫名其妙的错误,甚至是请求直接被服务器拒绝。

         举个例子,假如A页面上有一个链接,点击后跳转到B页面,假如我们直接用POST请求B页面,跳过了A页面,很可能被服务器拒绝,这时候就要设置一下Http头信息,xmlHttp.setRequestHeader(“Referer”,”A页面URL”);这样一来,就可以伪装成从A页面跳转过来的。

         再说说POST和GET在AJAX中的区别。如果使用GET方式请求数据,参数直接写在url后边即可,例如:api.ashx?hl=cn&weather=beiijng;而如果是用POST方式,参数要写在send方法中,例如xmlHttp.send(“hl=cn&weather=beijing”);。另外,使用POST方法要多关注Http头信息。

         关于POST和GET方式各自的特点,请读者自行google。

 

         附:

         点击下载Demo

 

 

你可能感兴趣的:(Google)