--Ajax 跨域取数据之服务端Proxy,附代码--

--------------------------------------------------------------
Ajax跨域取数据之原代码下载,下载地址:
https://files.cnblogs.com/enric1985/AjaxProxy.rar
希望对你有所帮助!
--------------------------------------------------------------
网上有许多关于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>
    
<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 的代码如下所示:

<script language="C#" runat="server">
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跨域的~`
我们在前台页面上加入如下代码:

 

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!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);" />
        
&nbsp;&nbsp;
        
<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" />
        
&nbsp;&nbsp; &nbsp;
        
<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

<%@ WebHandler Language="C#" Class="RegularProxy" %>

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

<%@ WebHandler Language="C#" Class="StreamingProxy" %>

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 跨域这个立场上去讲解!它取得数据后的页面效果如下图所示:

posted on 2008-06-14 22:38  酋长-Chief  阅读(1390)  评论(1编辑  收藏  举报

导航