域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。有一种简明的说法来解释广域跨域:跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。
在广域网环境中,由于浏览器的安全限制,网络连接的跨域访问时不被允许的,XmlHttpRequest也不例外。但有时候跨域访问资源是必需的。
同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。同源策略不阻止将动态脚本元素插入文档中。
不同域下的js可以相互访问,如:
www.a.com中通过 <script language="javascript" src="http://www.b.com:8088/sari/scripts/zy.js"></script> 可以访问www.b.com的zy.js
跨域传参解决方案1:
在浏览器中不能直接来跨域访问,而在服务器端没有跨域安全限制。这样的话,可以在服务端完成跨域访问,而在客户端来取得结果就可以了。这样做的缺点则是需要修改服务器端得代码。
跨域传参解决方案2:通过AJAX
由于Javascript 的安全机制,脚本是不允许跨域的 ( 安全的问题,浏览器默认是不支持跨域调用的 ) 。后来出现了一种叫 JSON with Padding 的技术,简称 JSONP .(原理参考 http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ ),应用 JSONP 可以实现 JSON 数据的跨域调用, jQuery 的 getJSON 放在 1.2 版本中已经能够跨域获取数据了。
首先修改hosts文件,以模拟两个域。
192.168.100.22 www.a.com
192.168.100.22 www.b.com
两个域名对应不同的工程:
www.a.com HuoDong
www.b.com sari
ps: www.a.com/HuoDong 和 www.b.com/sari 属于同一个域。
然后用www.a.com来访问www.b.com的一个方法,www.b.com返回json对象给www.a.com
HuoDong工程的jsp:
$.ajax({ type:"GET", //请求方式 url:"http://www.yue.com:8088/sari/samples/samples_viewParent.ac?jsoncallback=?", //必须有jsoncallback=?,否则请求将被游览器拒绝 cache: false, data:"age="+$("input:eq(0)").val(), //传参 dataType: "json", //返回值类型 success:function(json){ alert(json); } });
sari的Aciton:
public void doViewParentSubmit() throws GeneralException { // TODO Auto-generated method stub String Id = getRequest().getParameter("Id"); String jsoncallback = getRequest().getParameter("jsoncallback"); //必须有,否则无法返回json数据给a List list = new ArrayList(); list.add("11"); list.add("22"); try { JSONArray j = JSONArray.fromObject(list); PrintWriter p = getResponse().getWriter(); p.print(jsoncallback+"("+j+")"); p.close(); } catch (IOException e) { e.printStackTrace(); } }
注意:
1, 这里调用的地址中jsoncallback=? 是关键的所在!其中,符号会被 Query 自动替换成其他的回调方法的名称,具体过程和原理我们这里不理会。我们关心的是 jsoncallback=? 起什么作用了?原来 jsoncallback=? 被替换后,会把方法名称传给服务器。我们在服务器端要做什么工作呢?服务器要接受参数 jsoncallback ,然后把 jsoncallback 的值作为 JSON 数据方法名称返回 .
2, 服务器段把jsoncallback 的值作为方法名传回来 .
3, 输出json 数据时候 { 之前的是 (
3 通过ifream
在www.a.com中用
<a href="http://www.b.com:8088/sari/samples/samples_viewParent.ac" id="a1" name="a1.html" target="i">1</a> <iframe src="" id="iframe" name="i"></iframe>
ifream中可以得到www.b.com中的json对象
另:
判断两个地址是否跨域,是看该网页的document.domain,如果两个网页的该值不相同,则属于
跨域,例如:bbs.baidu.com 和 tieba.baidu.com虽然是都是二级域名,但是document.domain不相同话
依然属于跨域,所以还有一个解决跨域的问题就是在前台JSP页面中把两个地址的document.domain 设为一样的。如
if(location.href.indexOf("home.news.cn") != -1) { document.domain = "home.news.cn"; }
这样的话jnduan.home.news.cn和root.home.news.cn就不算跨域了。