AJAX跨域问题的解决办法
最近公司内部的architecture组正在热烈讨论AJAX,最后难免会谈到如何跨域这个问题,因为从AJAX诞生那天起,XMLHttprequest对象在firefox下不能跨域请求的问题就一直存在,等待浏览器们去解决这个问题显然不太现实,聪明的Web开发人员们早就想了一系列的方法来解决这个问题,下面列举两个比较不错的方法:
1. 使用中间层过渡的方式:
中间过渡,很明显,就是在AJAX与不同域的服务器进行通讯的中间加一层过渡,这一层过渡可以是PHP、JSP、c++等任何具备网络通讯功能的语言,由中间层向不同域的服务器进行读取数据的操作。拿PHP做一个例子,如果需要对不同域的某一个php进行通讯,现在客户端的 xmlhttprequest先query本域的一个PHP,然后由本域的这个PHP去和不同域的PHP进行通讯,然后由本域的PHP输出 response;
2. 使用<script>标签
这个方法是利用<script>标签中的src来query一个PHP获得response,因为<script>标签的src属性不存在跨域的问题。
举个例子来让大家看得更清楚一点吧:
<script LANGUAGE="Javascript" src="" id="get">
</script>
<script LANGUAGE="Javascript">
<!--
function get(url)
{
var obj = document.getElementById("get");
obj.src = url;
(obj.readStatus == 200)
{
alert(param);
}
}
function query()
{
get(get.php);
}
//-->
</script>
<BODY>
<INPUT TYPE="button" value="CLICK ME" onclick="query()">
</BODY>
</HTML>
其中get.php的代码是:
<?php
echo "var param = 'www.achome.cn'";
?>
最后的运行结果是,当你点击那个button,它会出现一个内容为”www.achome.cn”的对话框。
这个方法又叫做ajaj或者ajax without xmlHttprequest,把x换成了j,是因为使用了<script>标签而没有用到xml和xmlHttprequest的缘故。
怎么样,很简单吧,我看到过很多人不愿意去正视ajax所存在的技术瓶颈,其实AJAX更应该是Ajax而不是AJAX,突出第一个A是想强调其实AJAX发扬的是一种异步传输的方法,而不是具体到底使用了哪种技术。
asp中网页源代码的获取,跨域的实现
最近几天一直在研究怎样去掉用google翻译我博客的页面中的框架,最后得出结论没有完美解决方案。详情见次博文-http://www.daokers.cn/article/original/451.htm
我们知道静态程序是我们从服务器上下载网页后在本地执行,而动态网页是在服务器中执行然后返回给我们执行的结果,从而达到服务端和客服端交互的效果,这就是所谓的动态。那么获取网页源代码的方法我们也从这2个方面来着手。下面我就从测试google翻译的usg值为例详细说说网页源代码的获取,跨域的实现及 js的传值。
目标:获取http://www.daokerstest.com/test.asp&u=http://www.daokers.cn这个页面的源代码,U值为变量。
第一种方法,在本地执行程序获取指定网页源代码,这通过js代码加上xmlhttp组件来完成。
在test.js文件中。
程序代码
function translate() {
var currentUrl=window.location.href;//获取当前页面地址或者别的网站地址
var translateUrl="http://www.daokerstest.com/test.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//获取返回的源码值
document.write(myString)//传出此值
}
第二种方法,上面的方法最简单,但是最大的问题是如果想获取别的网站的源代码就存在跨域的问题,代码在 xmlhttp.open("GET",translateUrl,false);处将无法执行,那么我们可以让这个代码在服务器执行然后再传回来,也就是通过代理来解决跨域的问题。
这里只能通过一个代理页面来获取目标网页的源代码,这里代理页面为http://www.daokerstest.com/daili.asp
在test.js文件中。
程序代码
function translate() {
var currentUrl=window.location.href;//获取当前页面地址或者别的网站地址
var translateUrl="http://www.daokerstest.com/daili.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//获取返回的源码值
document.write(myString)//传出此值
}
daili.asp代码:
程序代码
<script language="JScript" runat="server">
function getusg() {
var getusgUrl="http://www.daokerstest.com/test.asp&u="+(Request.Item("id").Item||"");
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",getusgUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;
return myString;
}
Response.Write(getusg());
</script>
这里涉及到了asp和js之间的传值,这个方法相当的实用,是蓝色理想的小秦告诉我的。最开始我是用string=request("id")来获取,然后在js中<%=string%>调用,一直失败,最后小秦的提醒才让我如梦初醒。我严重忽视了server中js和asp的执行顺序,在 server中是先执行js然后执行asp代码,所以当js中调用string值时,asp代码还没有执行获取id值呢!用 Request.Item("id").Item就可以直接在js中获取参数值,从而成功的实现了绕过了跨域访问限制。
第三种方法,js可以获取网页源代码,asp也是可以的,并且不存在跨域的问题。js代码不变。
daili.asp代码:
程序代码
<%
function getHTTPPage(url)
dim Http
set Http=server.createobject("MSXml2.XmlHTTP")
Http.open "GET",url,false
Http.send()
if Http.readystate<>4 then
exit function
else
If Http.status=200 Then
response.write replace(BytesToBstr(http.responseBody,"gb2312"),chr(10),"")
End If
end if
getHTTPPage=bytesToBSTR(Http.responseBody,"GB2312")
set http=nothing
if err.number<>0 then err.Clear
end function
Function BytesToBstr(body,Cset)'转换代码,不然全是乱码
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
End Function
Dim Url,Html,Usg,id
id=Request("id")
Url="http://www.daokerstest.com/test.asp&u="+id
Html = getHTTPPage(Url)
Response.write Html
'此代码修改自http://www.stubc.com/thread-465-1-3.html
%>
这个就是直接在asp中用request获取参数,然后获取指定网页源代码。
从上面实例可见,都是利用XmlHTTP来获取别站的网页源代码,只要代码是在server执行就不存在跨域的问题。
<script LANGUAGE="Javascript" src="" id="get">
</script>
<script LANGUAGE="Javascript">
<!--
function get(url)
{
var obj = document.getElementById("get");
obj.src = url;
(obj.readStatus == 200)
{
alert(param);
}
}
function query()
{
get(get.php);
}
//-->
</script>
<BODY>
<INPUT TYPE="button" value="CLICK ME" onclick="query()">
</BODY>
</HTML>
<?php
echo "var param = 'www.achome.cn'";
?>
程序代码
function translate() {
var currentUrl=window.location.href;//获取当前页面地址或者别的网站地址
var translateUrl="http://www.daokerstest.com/test.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//获取返回的源码值
document.write(myString)//传出此值
}
程序代码
function translate() {
var currentUrl=window.location.href;//获取当前页面地址或者别的网站地址
var translateUrl="http://www.daokerstest.com/daili.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//获取返回的源码值
document.write(myString)//传出此值
}
程序代码
<script language="JScript" runat="server">
function getusg() {
var getusgUrl="http://www.daokerstest.com/test.asp&u="+(Request.Item("id").Item||"");
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",getusgUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;
return myString;
}
Response.Write(getusg());
</script>
程序代码
<%
function getHTTPPage(url)
dim Http
set Http=server.createobject("MSXml2.XmlHTTP")
Http.open "GET",url,false
Http.send()
if Http.readystate<>4 then
exit function
else
If Http.status=200 Then
response.write replace(BytesToBstr(http.responseBody,"gb2312"),chr(10),"")
End If
end if
getHTTPPage=bytesToBSTR(Http.responseBody,"GB2312")
set http=nothing
if err.number<>0 then err.Clear
end function
Function BytesToBstr(body,Cset)'转换代码,不然全是乱码
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
End Function
Dim Url,Html,Usg,id
id=Request("id")
Url="http://www.daokerstest.com/test.asp&u="+id
Html = getHTTPPage(Url)
Response.write Html
'此代码修改自http://www.stubc.com/thread-465-1-3.html
%>