实现天气预报功能
2013-08-05 22:58 昨日书 阅读(2528) 评论(12) 编辑 收藏 举报闲来无聊,写下此文
经常看见很多网站上有那种天气预报功能,自己之前也写过一个,不过属于那种涉及WCF服务引用那种,今天发现一个更为简单的方式来实现,使用Javascript和Ajax技术,极少后台代码,具体好与不好各位看官看了再说,尽管拍砖、、、
前置条件
作为程序员的我们木有天气数据,那些天气预报的数据肯定都来自中国气象局,我们需要采集相关数据到我们本地进行相应的处理,这里提供一个采集网址:http://www.weather.com.cn/data/cityinfo/101200101.html
在这个网址中有气象中心提供的相关数据,不过都是Json格式,有了数据就好办多了,接下来我们就来编码,弱弱的写下了如下JS代码:
1 <script type="text/javascript"> 2 var xmlHttpRequest = null; 3 //创建XMLHttpRequest 4 function createXmlHttpRequest() { 5 if (window.XMLHttpRequest) { 6 xmlHttpRequest = new XMLHttpRequest(); 7 } else if (window.ActiveXObject) { 8 xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 9 } 10 } 11 //调用Ajax 12 function sendRequest(url) { 13 if (xmlHttpRequest) { 14 xmlHttpRequest.open("GET", url, true); 15 xmlHttpRequest.onreadystatechange = onCallBack; 16 xmlHttpRequest.send(null); 17 } 18 } 19 //返回操作结果 20 function onCallBack() { 21 if (xmlHttpRequest.readyState == 4) { 22 if (xmlHttpRequest.status == 200) { 23 if (xmlHttpRequest.responseText != "") { 24 json = xmlHttpRequest.responseText; 25 } else { 26 alert("失败"); 27 } 28 } else { 29 alert("读取失败"); 30 } 31 } 32 } 33 34 function Test() { 35 createXmlHttpRequest(); //创建XMLHttpRequest对象 36 var url = "http://www.weather.com.cn/data/cityinfo/101010100.html"; //操作的文件 37 sendRequest(url, encodeURI(null)); 38 var jsonList = eval("(" + json + ")"); //获取Json 39 alert(jsonList); 40 } 41 </script>
通过这段Ajax调用,理论上我们可以获取到气象中心的天气预报数据,这段代码也完全木有错误,可是运行你就会发现弹出“读取错误”,很奇怪吧?为了让我们看到问题所在,我换一种方式,在浏览器地址栏输入第36行的地址,保存该网页到本地所建的项目中,然后将以上第36行代码改为刚保存网页所在路径,接着运行你会发现正确获取到了数据。这说明了一个问题,使用Ajax不可访问其他域的内容,也就是俗说的跨域问题,需要知道的一点是:Ajax是无法跨域的。好吧,我承认我很菜,直到写这篇随笔的时候我才发现这个问题,而且还弱弱的弄了好久,以为是自己的代码有问题,大神们见笑了!
怎么解决这里的Ajax跨域问题呢?
在网上搜索了很多,也看到了一系列这样的提问与回答,可是好多都是两个域我们都可以控制那种,而现在我面临的这个是我只能修改我这边的代码,数据端我无法修改任何东西。真的很纠结,最后使用JS还是无法完成,于是选择了后台代码,希望看到此文的大神给个提示,感激!
给出具体代码,其实说句实话,我自己都觉得弱爆了,觉得垃圾的尽管拍砖吧!!!
前端HTML+JavaScript代码
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Weather.Default" %> 2 3 <!DOCTYPE html> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 <title>天气预报</title> 9 <style type="text/css"> 10 </style> 11 <script type="text/javascript"> 12 var xmlHttpRequest = null; 13 //创建XMLHttpRequest 14 function createXmlHttpRequest() { 15 if (window.XMLHttpRequest) { 16 xmlHttpRequest = new XMLHttpRequest(); 17 } else if (window.ActiveXObject) { 18 xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 19 } 20 } 21 //调用Ajax 22 function sendRequest(url) { 23 if (xmlHttpRequest) { 24 xmlHttpRequest.open("GET", url, true); 25 xmlHttpRequest.onreadystatechange = onCallBack; 26 xmlHttpRequest.send(null); 27 } 28 } 29 //返回操作结果 30 function onCallBack() { 31 if (xmlHttpRequest.readyState == 4) { 32 if (xmlHttpRequest.status == 200) { 33 if (xmlHttpRequest.responseText != "") { 34 json = xmlHttpRequest.responseText; 35 } else { 36 alert("失败"); 37 } 38 } else { 39 alert("读取失败"); 40 } 41 } 42 } 43 function Test() { 44 createXmlHttpRequest(); //创建XMLHttpRequest对象 45 var citys = document.getElementById("citys"); 46 var index = citys.selectedIndex; 47 var cityid = citys[index].value; 48 var url = "MyHandler.ashx?city=" + cityid; //操作的文件 49 sendRequest(url, encodeURI(null)); 50 var jsonList = eval("(" + json + ")"); //获取Json 51 var weathernow = document.getElementById("weather"); 52 weathernow.innerHTML = jsonList[0]["weather"]; 53 var temp = document.getElementById("temp"); 54 temp.innerHTML=jsonList[0]["temp1"]+"~"+jsonList[0]["temp2"]; 55 } 56 </script> 57 </head> 58 <body> 59 <form id="form1" runat="server"> 60 <div> 61 <p> 62 <span>天气情况:</span><img src="#" alt="" /> 63 <span id="weather">天气</span> <span id="temp">温度</span> 64 </p> 65 <p> 66 <span>选择城市:</span> 67 <select id="citys"> 68 <option value="101200101">武汉</option> 69 <option value="101010100">北京</option> 70 <option value="101020100">上海</option> 71 <option value="101280101">广州</option> 72 </select> 73 <input type="button" value="查询天气" onclick="Test()" /> 74 </p> 75 </div> 76 </form> 77 </body> 78 </html>
后台一般应用处理程序代码
1 /// <summary> 2 /// MyHandler 的摘要说明 3 /// </summary> 4 public class MyHandler : IHttpHandler 5 { 6 private WebClient webclient = new WebClient(); 7 public void ProcessRequest(HttpContext context) 8 { 9 context.Response.ContentType = "text/plain"; 10 string cityid = context.Request.QueryString["city"];//101200101 11 string alldata = Weather("http://www.weather.com.cn/data/cityinfo/" + cityid + ".html").Substring(15); 12 string data = '['+alldata.Substring(0, alldata.Length - 1)+']'; 13 context.Response.Write(data); 14 } 15 16 public bool IsReusable 17 { 18 get 19 { 20 return false; 21 } 22 } 23 24 public string Weather(string url) 25 { 26 Uri uri = new Uri(url); 27 WebRequest webrequest = WebRequest.Create(url); 28 Stream myStream = webclient.OpenRead(uri); 29 StreamReader reader = new StreamReader(myStream, System.Text.Encoding.UTF8); 30 return reader.ReadToEnd(); 31 } 32 }
运行的结果如图所示:
现在我们可以很容易的查询天气情况了,不过有一点不是蛮好,是不是该弄个图标更直观呢???好吧,于是有经过简单的处理,得到了如下截图:
好的,本次随笔就到这里吧,本来想单纯的使用JS来实现的,对于跨域相关的知识不是蛮了解所以纠结了好久,虽然还是没有解决但至少通过这次随笔理解了跨域相关的问题。
简单结尾
留下一个问题:有两个不同的域A和B,现在B中有一个页面有A需要的数据,但是无法操作B的任何对象,如何实现?(大神看见,求解惑!)
最近实习有点不顺,总感觉这样的实习意义不大,而且感觉自学的效果还会更好些,同时也在纠结一个问题自己具体该走哪个方向、、、
------如果你觉得此文对你有所帮助,别忘了点击下右下角的推荐咯,谢谢!------