JQuery Ajax通過Handler訪問外部XML數(shù)據(jù)的代碼
更新時(shí)間:2010年06月01日 18:32:31 作者:
JQuery是一款不錯(cuò)的Javascript腳本框架,相信園子里的很多朋友對(duì)它都不陌生,我們?cè)陂_發(fā)Web應(yīng)用程序時(shí)難免會(huì)使用到Javascript腳本,而使用一款不錯(cuò)的腳本框架將會(huì)大大節(jié)省我們的開發(fā)時(shí)間, 并可以毫不費(fèi)力地實(shí)現(xiàn)很多非??岬男Ч?。
JQuery的使用非常簡(jiǎn)單,我們只需要從其官方網(wǎng)站上下載一個(gè)腳本文件并引用到頁面上即可,然后你就可以在你的腳本代碼中任意使用JQuery提供的對(duì)象和功能了。
在JQuery中使用Ajax方法異步獲取服務(wù)器資源非常簡(jiǎn)單,讀者可以參考其官方網(wǎng)站上提供的例子http://api.jquery.com/category/ajax/。當(dāng)然,作為客戶端腳本,JQuery也會(huì)遇到跨域訪問資源的問題,什么是跨域訪問呢?簡(jiǎn)單來說就是腳本所要訪問的資源屬于網(wǎng)站外部的資源,腳本所在的位置和資源所在的位置不在同一區(qū)域。默認(rèn)情況下,瀏覽器是不允許直接進(jìn)行資源的跨域訪問的,除非客戶端瀏覽器有設(shè)置,否則訪問會(huì)失敗。在這種情況下,我們一般都會(huì)采用在服務(wù)器端使用handler來解決,就是說在腳本和資源之間建立一個(gè)橋梁,讓腳本訪問本站點(diǎn)內(nèi)的handler,通過handler去訪問外部資源。這個(gè)是非常普遍的做法,而且操作起來也非常簡(jiǎn)單,因?yàn)闀?huì)經(jīng)常使用到,所以在此記錄一下,方便日后使用!
首先需要在網(wǎng)站中創(chuàng)建一個(gè)handler,在Visual Studio中新建一個(gè)Generic Handler文件,拷貝下面的代碼:
<%@ WebHandler Language="C#" Class="WebApplication1.Stock" %>
namespace WebApplication1
{
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Asynchronous HTTP handler for rendering external xml source.
/// </summary>
public class Stock : System.Web.IHttpAsyncHandler
{
private static readonly SafeList safeList = new SafeList();
private HttpContext context;
private WebRequest request;
/// <summary>
/// Gets a value indicating whether the HTTP handler is reusable.
/// </summary>
public bool IsReusable
{
get { return false; }
}
/// <summary>
/// Verify that the external RSS feed is hosted by a server on the safe list
/// before making an asynchronous HTTP request for it.
/// </summary>
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var u = context.Request.QueryString["u"];
var uri = new Uri(u);
if (safeList.IsSafe(uri.DnsSafeHost))
{
this.context = context;
this.request = HttpWebRequest.Create(uri);
return this.request.BeginGetResponse(cb, extraData);
}
else
{
throw new HttpException(204, "No content");
}
}
/// <summary>
/// Render the response from the asynchronous HTTP request for the RSS feed
/// using the response's Expires and Last-Modified headers when caching.
/// </summary>
public void EndProcessRequest(IAsyncResult result)
{
string expiresHeader;
string lastModifiedHeader;
string rss;
using (var response = this.request.EndGetResponse(result))
{
expiresHeader = response.Headers["Expires"];
lastModifiedHeader = response.Headers["Last-Modified"];
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream, true))
{
rss = reader.ReadToEnd();
}
}
var output = this.context.Response;
output.ContentEncoding = Encoding.UTF8;
output.ContentType = "text/xml;"; // "application/rss+xml; charset=utf-8";
output.Write(rss);
var cache = output.Cache;
cache.VaryByParams["u"] = true;
DateTime expires;
var hasExpires = DateTime.TryParse(expiresHeader, out expires);
DateTime lastModified;
var hasLastModified = DateTime.TryParse(lastModifiedHeader, out lastModified);
cache.SetCacheability(HttpCacheability.Public);
cache.SetOmitVaryStar(true);
cache.SetSlidingExpiration(false);
cache.SetValidUntilExpires(true);
DateTime expireBy = DateTime.Now.AddHours(1);
if (hasExpires && expires.CompareTo(expireBy) <= 0)
{
cache.SetExpires(expires);
}
else
{
cache.SetExpires(expireBy);
}
if (hasLastModified)
{
cache.SetLastModified(lastModified);
}
}
/// <summary>
/// Do not process requests synchronously.
/// </summary>
public void ProcessRequest(HttpContext context)
{
throw new InvalidOperationException();
}
}
/// <summary>
/// Methods for matching hostnames to a list of safe hosts.
/// </summary>
public class SafeList
{
/// <summary>
/// Hard-coded list of safe hosts.
/// </summary>
private static readonly IEnumerable<string> hostnames = new string[]
{
"cnblogs.com",
"msn.com",
"163.com",
"csdn.com"
};
/// <summary>
/// Prefix each safe hostname with a period.
/// </summary>
private static readonly IEnumerable<string> dottedHostnames =
from hostname in hostnames
select string.Concat(".", hostname);
/// <summary>
/// Tests if the <paramref name="hostname" /> matches exactly or ends with a
/// hostname from the safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
public bool IsSafe(string hostname)
{
return MatchesHostname(hostname) || MatchesDottedHostname(hostname);
}
/// <summary>
/// Tests if the <paramref name="hostname" /> ends with a hostname from the
/// safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
private static bool MatchesDottedHostname(string hostname)
{
return dottedHostnames.Any(host => hostname.EndsWith(host, StringComparison.InvariantCultureIgnoreCase));
}
/// <summary>
/// Tests if the <paramref name="hostname" /> matches exactly with a hostname
/// from the safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
private static bool MatchesHostname(string hostname)
{
return hostnames.Contains(hostname, StringComparer.InvariantCultureIgnoreCase);
}
}
}
我給出的例子中是想通過Ajax異步取得msn站點(diǎn)上微軟的股票信息,其外部資源地址為http://money.service.msn.com/StockQuotes.aspx?symbols=msft,我們?cè)陧撁嫔线@樣使用JQuery api通過Handler來訪問數(shù)據(jù):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<div id="con">
<span id="loader">loading...</span>
</div>
<script type="text/javascript">
function getData() {
$("#loader").ajaxStart(function() {
$(this).show();
});
$("#loader").ajaxComplete(function() {
$(this).hide();
});
$.ajax({
type: "GET",
url: "Stock.ashx?u=http://money.service.msn.com/StockQuotes.aspx?symbols=msft",
dataType: "xml",
success: function(data) {
var last = "";
var change = "";
var percentchange = "";
var volume = "";
var cap = "";
var yearhigh = "";
var yearlow = "";
$(data).find('ticker').each(function() {
last = $(this).attr('last');
change = $(this).attr('change');
percentchange = $(this).attr('percentchange');
volume = $(this).attr('volume');
cap = $(this).attr('marketcap');
yearhigh = $(this).attr('yearhigh');
yearlow = $(this).attr('yearlow');
document.getElementById('con').innerHTML = '<span>name:' + last + ' high:' + volume + ' low:' + cap + '</span>';
})
}
});
}
$(window).load(getData);
</script>
</body>
</html>
下面是實(shí)現(xiàn)的結(jié)果:
name:25.8 high:67,502,221 low:$226,107,039,514
Handler的寫法基本都大同小異,因此可以寫成一個(gè)通用的例子,以后如遇到在腳本中需要跨域訪問資源時(shí)便可以直接使用!代碼記錄于此,方便查閱。
在JQuery中使用Ajax方法異步獲取服務(wù)器資源非常簡(jiǎn)單,讀者可以參考其官方網(wǎng)站上提供的例子http://api.jquery.com/category/ajax/。當(dāng)然,作為客戶端腳本,JQuery也會(huì)遇到跨域訪問資源的問題,什么是跨域訪問呢?簡(jiǎn)單來說就是腳本所要訪問的資源屬于網(wǎng)站外部的資源,腳本所在的位置和資源所在的位置不在同一區(qū)域。默認(rèn)情況下,瀏覽器是不允許直接進(jìn)行資源的跨域訪問的,除非客戶端瀏覽器有設(shè)置,否則訪問會(huì)失敗。在這種情況下,我們一般都會(huì)采用在服務(wù)器端使用handler來解決,就是說在腳本和資源之間建立一個(gè)橋梁,讓腳本訪問本站點(diǎn)內(nèi)的handler,通過handler去訪問外部資源。這個(gè)是非常普遍的做法,而且操作起來也非常簡(jiǎn)單,因?yàn)闀?huì)經(jīng)常使用到,所以在此記錄一下,方便日后使用!
首先需要在網(wǎng)站中創(chuàng)建一個(gè)handler,在Visual Studio中新建一個(gè)Generic Handler文件,拷貝下面的代碼:
復(fù)制代碼 代碼如下:
<%@ WebHandler Language="C#" Class="WebApplication1.Stock" %>
namespace WebApplication1
{
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Asynchronous HTTP handler for rendering external xml source.
/// </summary>
public class Stock : System.Web.IHttpAsyncHandler
{
private static readonly SafeList safeList = new SafeList();
private HttpContext context;
private WebRequest request;
/// <summary>
/// Gets a value indicating whether the HTTP handler is reusable.
/// </summary>
public bool IsReusable
{
get { return false; }
}
/// <summary>
/// Verify that the external RSS feed is hosted by a server on the safe list
/// before making an asynchronous HTTP request for it.
/// </summary>
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var u = context.Request.QueryString["u"];
var uri = new Uri(u);
if (safeList.IsSafe(uri.DnsSafeHost))
{
this.context = context;
this.request = HttpWebRequest.Create(uri);
return this.request.BeginGetResponse(cb, extraData);
}
else
{
throw new HttpException(204, "No content");
}
}
/// <summary>
/// Render the response from the asynchronous HTTP request for the RSS feed
/// using the response's Expires and Last-Modified headers when caching.
/// </summary>
public void EndProcessRequest(IAsyncResult result)
{
string expiresHeader;
string lastModifiedHeader;
string rss;
using (var response = this.request.EndGetResponse(result))
{
expiresHeader = response.Headers["Expires"];
lastModifiedHeader = response.Headers["Last-Modified"];
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream, true))
{
rss = reader.ReadToEnd();
}
}
var output = this.context.Response;
output.ContentEncoding = Encoding.UTF8;
output.ContentType = "text/xml;"; // "application/rss+xml; charset=utf-8";
output.Write(rss);
var cache = output.Cache;
cache.VaryByParams["u"] = true;
DateTime expires;
var hasExpires = DateTime.TryParse(expiresHeader, out expires);
DateTime lastModified;
var hasLastModified = DateTime.TryParse(lastModifiedHeader, out lastModified);
cache.SetCacheability(HttpCacheability.Public);
cache.SetOmitVaryStar(true);
cache.SetSlidingExpiration(false);
cache.SetValidUntilExpires(true);
DateTime expireBy = DateTime.Now.AddHours(1);
if (hasExpires && expires.CompareTo(expireBy) <= 0)
{
cache.SetExpires(expires);
}
else
{
cache.SetExpires(expireBy);
}
if (hasLastModified)
{
cache.SetLastModified(lastModified);
}
}
/// <summary>
/// Do not process requests synchronously.
/// </summary>
public void ProcessRequest(HttpContext context)
{
throw new InvalidOperationException();
}
}
/// <summary>
/// Methods for matching hostnames to a list of safe hosts.
/// </summary>
public class SafeList
{
/// <summary>
/// Hard-coded list of safe hosts.
/// </summary>
private static readonly IEnumerable<string> hostnames = new string[]
{
"cnblogs.com",
"msn.com",
"163.com",
"csdn.com"
};
/// <summary>
/// Prefix each safe hostname with a period.
/// </summary>
private static readonly IEnumerable<string> dottedHostnames =
from hostname in hostnames
select string.Concat(".", hostname);
/// <summary>
/// Tests if the <paramref name="hostname" /> matches exactly or ends with a
/// hostname from the safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
public bool IsSafe(string hostname)
{
return MatchesHostname(hostname) || MatchesDottedHostname(hostname);
}
/// <summary>
/// Tests if the <paramref name="hostname" /> ends with a hostname from the
/// safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
private static bool MatchesDottedHostname(string hostname)
{
return dottedHostnames.Any(host => hostname.EndsWith(host, StringComparison.InvariantCultureIgnoreCase));
}
/// <summary>
/// Tests if the <paramref name="hostname" /> matches exactly with a hostname
/// from the safe host list.
/// </summary>
/// <param name="hostname">Hostname to test</param>
/// <returns>True if the hostname matches</returns>
private static bool MatchesHostname(string hostname)
{
return hostnames.Contains(hostname, StringComparer.InvariantCultureIgnoreCase);
}
}
}
我給出的例子中是想通過Ajax異步取得msn站點(diǎn)上微軟的股票信息,其外部資源地址為http://money.service.msn.com/StockQuotes.aspx?symbols=msft,我們?cè)陧撁嫔线@樣使用JQuery api通過Handler來訪問數(shù)據(jù):
復(fù)制代碼 代碼如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<div id="con">
<span id="loader">loading...</span>
</div>
<script type="text/javascript">
function getData() {
$("#loader").ajaxStart(function() {
$(this).show();
});
$("#loader").ajaxComplete(function() {
$(this).hide();
});
$.ajax({
type: "GET",
url: "Stock.ashx?u=http://money.service.msn.com/StockQuotes.aspx?symbols=msft",
dataType: "xml",
success: function(data) {
var last = "";
var change = "";
var percentchange = "";
var volume = "";
var cap = "";
var yearhigh = "";
var yearlow = "";
$(data).find('ticker').each(function() {
last = $(this).attr('last');
change = $(this).attr('change');
percentchange = $(this).attr('percentchange');
volume = $(this).attr('volume');
cap = $(this).attr('marketcap');
yearhigh = $(this).attr('yearhigh');
yearlow = $(this).attr('yearlow');
document.getElementById('con').innerHTML = '<span>name:' + last + ' high:' + volume + ' low:' + cap + '</span>';
})
}
});
}
$(window).load(getData);
</script>
</body>
</html>
下面是實(shí)現(xiàn)的結(jié)果:
name:25.8 high:67,502,221 low:$226,107,039,514
Handler的寫法基本都大同小異,因此可以寫成一個(gè)通用的例子,以后如遇到在腳本中需要跨域訪問資源時(shí)便可以直接使用!代碼記錄于此,方便查閱。
您可能感興趣的文章:
- JQuery的ajax獲取數(shù)據(jù)后的處理總結(jié)(html,xml,json)
- Jquery Ajax學(xué)習(xí)實(shí)例 向頁面發(fā)出請(qǐng)求,返回XML格式數(shù)據(jù)
- jQuery+ajax讀取并解析XML文件的方法
- JavaScript原生xmlHttp與jquery的ajax方法json數(shù)據(jù)格式實(shí)例
- 通過AJAX的JS、JQuery兩種方式解析XML示例介紹
- 用JQuery 實(shí)現(xiàn)AJAX加載XML并解析的腳本
- jQuery 利用$.ajax 時(shí)獲取原生XMLHttpRequest 對(duì)象的方法
- Jquery Ajax解析XML數(shù)據(jù)(同步及異步調(diào)用)簡(jiǎn)單實(shí)例
- Jquery通過Ajax訪問XML數(shù)據(jù)的小例子
- jQuery基于Ajax實(shí)現(xiàn)讀取XML數(shù)據(jù)功能示例
相關(guān)文章
jQuery實(shí)現(xiàn)鼠標(biāo)滑動(dòng)切換圖片
這篇文章主要為大家詳細(xì)介紹了jQuery實(shí)現(xiàn)鼠標(biāo)滑動(dòng)切換圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
GridView中獲取被點(diǎn)擊行中的DropDownList和TextBox中的值
本文為大家介紹下如何通過點(diǎn)擊GridView中的a標(biāo)簽獲取被點(diǎn)擊行中的下拉框和文本框中的值,具體實(shí)現(xiàn)嗲嗎如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07
為什么要在引入的css或者js文件后面加參數(shù)的詳細(xì)講解
為什么要在引入的css或者js文件后面加參數(shù)的詳細(xì)講解,需要的朋友可以參考一下2013-05-05
jquery實(shí)現(xiàn)垂直手風(fēng)琴菜單
這篇文章主要為大家詳細(xì)介紹了jquery實(shí)現(xiàn)垂直手風(fēng)琴菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
基于jQuery實(shí)現(xiàn)Tabs選項(xiàng)卡自定義插件
這篇文章主要為大家詳細(xì)介紹了基于jQuery實(shí)現(xiàn)Tabs選項(xiàng)卡自定義插件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
詳解JavaScript中jQuery和Ajax以及JSONP的聯(lián)合使用
這篇文章主要介紹了詳解JavaScript中jQuery和Ajax以及JSONP的聯(lián)合使用,jQuery庫和Ajax異步結(jié)構(gòu)以及JSON數(shù)據(jù)傳輸也是JS日常編程中最常用到的東西,需要的朋友可以參考下2015-08-08
用jquery實(shí)現(xiàn)自定義風(fēng)格的滑動(dòng)條實(shí)現(xiàn)代碼
用jquery實(shí)現(xiàn)自定義風(fēng)格的滑動(dòng)條的實(shí)現(xiàn)代碼,需要的朋友可以參考下。2011-04-04
Jquery實(shí)現(xiàn)仿新浪微博獲取文本框能輸入的字?jǐn)?shù)代碼
Jquery實(shí)現(xiàn)仿新浪微博獲取文本框所能輸入的字?jǐn)?shù),感興趣的朋友可以研究一下代碼方便你折騰,希望本文提供的方法可以幫助到你2013-02-02

