zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    crontab与系统时间不一致
    MySQL构造测试数据
    【SQL优化】SQL优化工具
    mysql case when then 使用
    update没带where,寻找问题的思路
    线程池
    线程理论
    数据共享
    进程池
    管道
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/2858201.html
Copyright © 2011-2022 走看看