js跨域

本文详细介绍了JavaScript在不同域间进行数据传输的原理及方法,包括同源策略的概念、JSONP跨域实现方式,并探讨了如何利用window.name和修改document.domain来实现跨子域访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

JS在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
下表给出了相对http://store.company.com/dir/page.html同源检测的结果:

URL结果原因
http://store.company.com/dir2/other.html成功
http://store.company.com/dir/inner/another.html成功
https://store.company.com/dir/inner/secure.html失败协议头不同(https与http)
http://store.company.com:8080/dir/page.html失败端口不同
http://news.company.com/dir/page.html失败主机名不一样

原理

A上的页面获取B上的资源,浏览器会检查服务器B的HTTP头(HEAD请求),如果Access-Control-Allow-Origin中有A,或者是通配符*,浏览器就会允许跨域。
域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系(即Trust Relation)。信任关系是连接在域与域之间的桥梁。当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理。 有一种简明的说法来解释广域跨域:跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的。
在广域网环境中,由于浏览器的安全限制,网络连接的跨域访问时不被允许的,XmlHttpRequest也不例外。但有时候跨域访问资源是必需的。
同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。同源策略不阻止将动态脚本元素插入文档中。

解决方法

理论

参考理论一

在浏览器中不能直接来跨域访问,而在服务器端没有跨域安全限制。
这样的话,可以在服务端完成跨域访问,而在客户端来取得结果就可以了。

参考理论二

同源策略不阻止动态脚本元素插入,脚本访问可以跨域。

jsonp跨域

js实现

@RequestMapping(value="/mytry",method={RequestMethod.POST,RequestMethod.GET})
    public void mytry(@RequestParam(value="callback")String callback, HttpServletRequest request, HttpServletResponse response) throws IOException{
        String str = "<script>"+callback+"('abc')</script>";
        PrintWriter out = response.getWriter();
        response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
        System.out.println(str);
        out.print(str);
    }

jquery实现(比较方便快捷)

java后台代码:

@RequestMapping(value="/mytry",method={RequestMethod.POST,RequestMethod.GET})
    public void mytry3(HttpServletRequest request, HttpServletResponse response) throws IOException{
        String callback =request.getParameter("callback");//jquery生成的自定义函数名 
        response.setCharacterEncoding("UTF-8"); 
        response.setContentType("text/html;charset=utf-8"); 
        PrintWriter out = response.getWriter(); 
        //返回json格式字符串,注意向前台输出的格式必须为 callback(json格式的字符串); 
        //callback是jquery生成的自定义函数名,返回这种格式,前台jquery代码会自动替换 
        //回调函数为此callback函数,从而达到跨域的效果,网上还有其他的跨域方案如:AJAJ 
        //原理应该也是和此方法一样。缺点是:返回数据量不宜过大,安全性差,建议重要数据不 
        //要通过这种形式传递。 
        out.print(callback+"({name:'nowuseeme',gender:'man'});"); 
        out.flush(); 
        out.close(); 
    }

jquery代码:

$(function(){
    var url = "http://127.0.0.1:8080/myproject/mytry?callback=?"; 
    $.getJSON(url,function(data, status, xhr){
        console.log(data.name);
    });
});

浏览器控制台打印结果:

nowuseeme

使用window.name跨域

修改document.domain来跨子域

参考

http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
http://www.cnblogs.com/2050/p/3191744.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值