實現天氣預報功能


閑來無聊,寫下此文

經常看見很多網站上有那種天氣預報功能,自己之前也寫過一個,不過屬於那種涉及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>
View Code

后台一般應用處理程序代碼

 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的任何對象,如何實現?(大神看見,求解惑!)

最近實習有點不順,總感覺這樣的實習意義不大,而且感覺自學的效果還會更好些,同時也在糾結一個問題自己具體該走哪個方向、、、

------如果你覺得此文對你有所幫助,別忘了點擊下右下角的推薦咯,謝謝!------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM