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

原文地址:https://www.cnblogs.com/iyangyuan/p/2858201.html