閑來無聊,寫下此文
經常看見很多網站上有那種天氣預報功能,自己之前也寫過一個,不過屬於那種涉及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的任何對象,如何實現?(大神看見,求解惑!)
最近實習有點不順,總感覺這樣的實習意義不大,而且感覺自學的效果還會更好些,同時也在糾結一個問題自己具體該走哪個方向、、、
------如果你覺得此文對你有所幫助,別忘了點擊下右下角的推薦咯,謝謝!------