AJAX跨域验证 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <HTML xmlns="http://www.w3.org/1999/xhtml"> <HEAD><TITLE>AJAX跨域验证</TITLE> <script> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } function hello() { var url = 'http://www.google.com'; createXMLHttpRequest(); xmlHttp.onreadystatechange = showResponse; xmlHttp.open("GET", url, true); xmlHttp.send(null); } function showResponse(){ if(xmlHttp.readyState == 4) { if(xmlHttp.status == 200) { document.getElementById("result").setAttribute("value",xmlHttp.responseText) ; } } } </script> </HEAD> <BODY> <input type="button" value="hello" onclick="hello()"><br/><br/> <textarea id="result" name="result" cols=100 rows=100 ></textarea> </BODY> </HTML>
具体情况有: 一、本域和子域的相互访问: http://www.aa.com/和book.aa.com 二、本域和其他域的相互访问: http://www.aa.com/和http://www.bb.com/ 用 iframe 三、本域和其他域的相互访问: http://www.aa.com/和http://www.bb.com/ 用 XMLHttpRequest访问代理 四、本域和其他域的相互访问: http://www.aa.com/和http://www.bb.com/ 用 JS创建动态脚本 今 天主要讨论第4中解决方案,这个和上个的区别就是请求是使用<script>标签来请求的,这个要求也是两个域都是由你来开发才行。原理就是 JS文件注入,在本域内的a内生成一个JS标签,它的SRC指向请求的另外一个域的某个页面b,b返回数据即可,可以直接返回JS的代码。因为 script的src属性是可以跨域的。 这里我们需要用到JQuery.getScript(url, callback)方法,url是脚本文件的URL路劲,callback函数在脚本资源已被加载和求值后调用的回调函数。 首先在bb.com创建一个js文件,test.js 复制代码 代码如下: var ojb = {msg:'js跨域请求成功'}; 然后在aa.com的页面上使用$.getScript加载test.js脚本 复制代码 代码如下: $(function() { $.getScript('http://www.bb.com/test.js', function() { if (ojb) { alert(obj.msg); } }); }); 使用$.getScript函数的最大好处就是可以保证,脚本加载完毕后调用回调函数。 个人感觉这种方法比使用代理和iframe要简单一些。
最近做个人网站遇到AJAX跨子域名的问题。 偶尔看到baidu的通行证处理都是在二级域名passport.baidu.com中处理的, 但是baidu很多地方登录都好像是用ajax处理的,他是怎么做的呢?研究了一下,发现一个小技巧。 不防让大家也借鉴一下。 在http://zhidao.baidu.com/ 未登录用户回答问题时会用iframe调用http://zhidao.baidu.com/userlogin.html userlogin.html有下面的javascript <SCRIPT LANGUAGE="JavaScript"> document.domain="baidu.com"; <!-- function G(id){if(typeof(id)=="string"){return document.getElementById(id);}return id;} function showInfo(obj){ if(obj.checked == true){ G("memInfo").style.display="block"; }else{ G("memInfo").style.display="none"; } } function request(id,url){ oScript = document.getElementById(id); var head = document.getElementsByTagName("head").item(0); if (oScript) { head.removeChild(oScript); } oScript = document.createElement("script"); oScript.setAttribute("src", url); oScript.setAttribute("id",id); oScript.setAttribute("type","text/javascript"); oScript.setAttribute("language","javascript"); head.appendChild(oScript); return oScript; } var loginTimer=null; var loginState=-1; var tryTime=0; function PSP_ik(isOk){ if(isOk==0){ G("errorInfo").style.display="none"; loginState=1; if(parent.loginSuccess){ parent.Pop.hide(); parent.loginSuccess(); } } else { loginFalse(); } } function loginFalse(){ loginState=0; var err=G("errorInfo"); err.innerHTML="用户名或密码错误,请重新登录"; err.style.display="block"; G("username").focus(); tryTime++; if(tryTime>1){ onLoginFailed(); } } function onLoginFailed(){ if(parent.onLoginFailed){ parent.Pop.hide(); parent.loginFailed(); }else{ document.login.u.value=escape("http://zhidao.baidu.com/q"+parent.location.search); doucment.login.submit(); } } function loginTimeout(){ if(loginState==-1){ var err=G("errorInfo"); err.innerHTML="操作超时,请重新登录"; err.style.display="block"; G("username").focus(); } } function userLogin(){ var username=G('username').value; var password=G('password').value; var memPassport=G('memPassport').checked?"on":"off"; if(username.length<=0||password.length<=0){G("username").focus();return false;} var url = 'https://passport.baidu.com/?logt&tpl=ik&t=0&keyname=ik&mem_pass='+memPassport+'&username='+username + '&loginpass=' +escape(password)+ '&s=' + (new Date()).getTime(); loginState=-1; var login=request("loginScript",url); loginTimer = setTimeout(loginTimeout, 5000); } window.onload=function(){ document.loginForm.username.focus(); document.getElementById("username").focus(); } //--> </SCRIPT> 我们可以看到request方法处理异步请求使用动态往head中添加script而不是用xmlhttp发送get请求。 妙就妙在这。我们知道调用javascript是没有域的限制的。当加载完成时一样会执行。 当然请求参数只能通过拼url的方式了。 url通过服务器处理后直接输出loginFalse()或者PSP_ik(); 非常优雅的解决了跨域的问题。 这让我们想到了用iframe当ajax上传文件一样异曲同工。 如果不需要服务器反馈,google的点击计数用new img().src=...; 当然baidu这段脚本中还有一些小的技巧也值得我们学习。 总结一句 活学活用 不要钻牛角尖,要不等我们解决ajax跨域的时候花儿也谢了
修改 js document domain <head> <title>a remote dialog</title> <script> <!-- document.domain = "mycompany.com"; onload = function() { var args = window.dialogArguments; alert("You send me: " + args.content); btnCan.onclick = function() { window.returnValue = "Yes I do, I hear you from " + document.domain; close(); } } --> </script> </head> <body> Im here, Im a dialog <br> I will return something to the main window<br> <input id="btnCan" type="button" style="text-align:center;" value="Close"> </body> </html>