--Ajax 跨域取数据之服务端Proxy,附代码--
--------------------------------------------------------------
Ajax跨域取数据之原代码下载,下载地址:
https://files.cnblogs.com/enric1985/AjaxProxy.rar
希望对你有所帮助!
--------------------------------------------------------------
网上有许多关于Ajax跨域问题的解决方法,看他们的做法都是如下所示:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>无标题页</title>
<script language="javascript" type="text/javascript">
function loadContent()
{
var s=document.createElement('SCRIPT');
s.src='http://localhost:3164/JavaScriptTest/DomSamples/XMLHttpRequest/Ajax跨域-js/default.aspx?f=setDivContent';
document.body.appendChild(s);
}
function setDivContent(v)
{
var dv = document.getElementById("dv");
dv.innerHTML = v;
}
</script>
</head>
<body>
<div id="dv"></div>
<input type="button" value="Click Me" onclick="loadContent()"/>
</body>
</html>
default.aspx 的代码如下所示:
void Page_Load(object sender, EventArgs e)
{
string f = Request.QueryString["f"];
Response.Clear();
Response.ContentType = "application/x-javascript";
Response.Write(String.Format(@"
{0}('{1}');",
f,
DateTime.Now));//setDivContent(DateTime.Now);
Response.End();
}
</script>
这种做法个人认为不是太妥,在解决问题时也不是很灵活. 在大数据量且所返回的数据有大量的html代码的时候总是会报 js 错误,实在是太不理想了!!!难道说除了这种方法就无法跨域取其它站点的数据了吗?答案是否定的!~~~```
通过 Server side Proxy 就可以很好解决 Ajax 跨域的问题!
1).RegularProxy
2).StreamingProxy
下面我们就来看看它是如何Ajax跨域的~`
我们在前台页面上加入如下代码:
<!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 runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="btnGetRegular" type="button" value="获取数据(RegularProxy)" onclick="getData(this);" />
<input id="btnGetStreaming" type="button" value="获取数据(StreamingProxy)" onclick="getData(this);" /><br />
<br />
<input type="text" id="url" value="http://www.5173.com/ajax.axd?methodName=GETHOTGAME" style="width: 378px" />
<br />
<br />
</div>
<div id="divConsole"></div>
</form>
</body>
<script language="javascript" type="text/javascript">
/*
Add by chief 2008.06.05
*/
var request;
function getData(_this)
{
var contentUrl = $get('url').value;
var isJson = false;
//判断是Regular,还是Stream Proxy进行Ajax跨域取数据
if(_this.id=="btnGetRegular")
{
download("RegularProxy.ashx",contentUrl,false,completeCallback);
}
else
{
download("StreamingProxy.ashx",contentUrl,false,completeCallback);
}
}
function download(proxyUrl, contentUrl, isJson, completeCallback)
{
request = getRequestInstance();
request.onreadystatechange = completeCallback;
var isCache = true;
var url = proxyUrl + "?url=" + escape(contentUrl) + (isJson ? "&type=" + escape("application/json") : "") + "&cache=" + (isCache ? "10" : "0");
request.open("get",url,false);
request.send(null);
}
function completeCallback()
{
var ready = request.readyState;
var data=null;
{
if(ready==4)
{
data=request.responseText;
$get('divConsole').innerHTML = data;
}
else
{
$get('divConsole').text = "加载中";
}
}
}
function getRequestInstance()
{
var req = null;
if(window.XMLHttpRequest)
{
req = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
return req;
}
function $get(id)
{
return document.getElementById(id);
}
</script>
</html>
页面如下图所示:
当点击 RegularProxy时, 就会调用前台 js 方法 download("RegularProxy.ashx",contentUrl,false,completeCallback);
StreamingProxy 时,就会调用前台 js 方法 download("StreamingProxy.ashx",contentUrl,false,completeCallback);
ok, 下面我们就要看看代理类 RegularProxy.ashx, 和 StreamingProxy.ashx 的具体实现了!
1).RegularProxy.ashx
using System;
using System.Web;
using System.Net;
public class RegularProxy : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
string url = context.Request["url"];
int cacheDuration = Convert.ToInt32(context.Request["cache"] ?? "0");
string contentType = context.Request["type"];
// We don't want to buffer because we want to save memory
context.Response.Buffer = false;
// Serve from cache if available
if (cacheDuration > 0)
{
if (context.Cache[url] != null)
{
context.Response.BinaryWrite(context.Cache[url] as byte[]);
context.Response.Flush();
return;
}
}
using (WebClient client = new WebClient())
{
if (!string.IsNullOrEmpty(contentType))
client.Headers["Content-Type"] = contentType;
client.Headers["Accept-Encoding"] = "gzip";
client.Headers["Accept"] = "*/*";
client.Headers["Accept-Language"] = "en-US";
client.Headers["User-Agent"] =
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6";
byte[] data;
data = client.DownloadData(url);
if (!context.Response.IsClientConnected) return;
// Deliver content type, encoding and length as it is received from the external URL
context.Response.ContentType = client.ResponseHeaders["Content-Type"];
string contentEncoding = client.ResponseHeaders["Content-Encoding"];
string contentLength = client.ResponseHeaders["Content-Length"];
if (!string.IsNullOrEmpty(contentEncoding))
context.Response.AppendHeader("Content-Encoding", contentEncoding);
if (!string.IsNullOrEmpty(contentLength))
context.Response.AppendHeader("Content-Length", contentLength);
if (data.Length > 0)
{
context.Response.OutputStream.Write(data, 0, data.Length);
context.Response.Flush();
}
}
}
public bool IsReusable
{
get {
return false;
}
}
}
这主要通过 WebClient 这个 object 去打开一个去下载指定 url 的数据. 它所做的事情就是这么简单! 然后再返回数据到前台.效果如下图所示:
2).StreamingProxy.ashx
using System;
using System.Web;
using System.Net;
using System.IO;
using System.Text;
public class StreamingProxy : IHttpHandler
{
const int BUFFER_SIZE = 8 * 1024;
public void ProcessRequest (HttpContext context)
{
string url = context.Request["url"];
int cacheDuration = Convert.ToInt32(context.Request["cache"] ?? "0");
string contentType = context.Request["type"];
WebRequest wr = WebRequest.Create(url);
WebResponse wres = wr.GetResponse();
Encoding resEncoding = System.Text.Encoding.GetEncoding("gb2312");
StreamReader sr = new StreamReader(wres.GetResponseStream(), resEncoding);
string html = sr.ReadToEnd();
sr.Close();
wres.Close();
context.Response.Write("<br/><br/><br/><h2>WebRequest 获取的数据:</h2><br/>");
context.Response.Write(html);
}
public bool IsReusable
{
get {
return false;
}
}
}
主要就是通过 WebRequest object 去获取数据然后返回.这些都是C#当中的简单对象我就不多说明了!~~`呵呵....我的重点只是从如何解决Ajax 跨域这个立场上去讲解!它取得数据后的页面效果如下图所示:
He works his work in mysterious way!