视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
深入分析Javascript跨域问题_javascript技巧
2020-11-27 21:37:14 责编:小采
文档
跨域是什么?

假设a.com/get.html需要获取b.com/data.html中的数据,而这里a.com和b.com并不是同一台服务器,这就是跨域跨域会涉及到Javascript的同源策略,简单来说就是为了保护网站的安全,不被外域(非同源)服务器的js修改本网站内容。
引用一个表格,看一下引起跨因的条件有哪些:

但是有时候我们确实需要这么做,那么我们有哪些方法呢?

1、JsonP

提到跨域不能不先提及jsonp。jsonp其实是JavacScript Object Notation with Padding的简称,可以理解成填充了内容的json格式数据。
因为以上声明了callback并且调用外域b.com的data.js,而data.js中调用:
callback({msg:"tqtan"});
这样当调用引用外域的js就会调用本地的callback()从而实现数据传输。
上面是只是简单的跨域,我们来看jQuery的真正的运用。

jQuery中的ajax可拉取外域的数据,通过两种方法:

1、$.getJSON()

这种方法简单粗暴,请求外域Json。

代码如下:
$.getJSON("http://b.com/dataServlet?callback=?",function(data){
console.log(data.msg);
});

假设上述请求访问b.com下的servlet页面,传的参数为callback=?,jQuery会自动生成字符串填补占位符?,例如callback=jQuery17207481773362960666_1332575486681。这就声明了与服务器的唯一标示,服务器只需要返回带有这个callback值的json格式数据即可,例如:

代码如下:
//dataServlet.java
String callback = req.getParameter("callback");
PrintWriter out = resp.getWriter();
out.print(callback+"('msg','tqtan')");

这样就能成功获取非同源服务器的数据了。

2、$.ajax()

实现原理和上面一样,只是可以自定义更多链接。



可以自定义callback的名字,这里改为'tqtan',同时这里可以传值words=hi。
注意了,JsonP格式只能是以GET形式请求服务器。

2、document.domain

这种方法只适用于主域相同,而子域不同的跨域。
也就是get.a.com和data.a.com的跨域问题,解决方法很简单:
若get.a.com/get.html需要获取data.a.com/data.html的数据,首先在get.html插入一个iframe,src指向data.a.com/data.html,然后在data.html写上document.domain='a.com';即可操纵data.html内的内容。



3、url hash

你也可以通过url的hash来实现跨域。hash就是url#后面的内容,例如http://targetkiller.net/index.html#data,这里#data就是hash。怎么用这个实现跨域呢?

还是那个例子,a.com/get.html需要获取b.com/data.html,首先在get.html建立一个iframe,src还是指向data.html,后面带上hash值实现传参。另一端data.html根据获取的hash作出响应,自身也创建一个iframe,src指向a.com/proxy.html,并把响应数据添加到hash。之后,a.com/proxy.html只需要修改在同一a.com父域的get.html的hash即可。最后,怎样获取数据呢?只需要在get.html写一个定时器setInterval,定期监听有无新的hash即可。

看到这里,你可能感到开始乱了,几个问题:

1.proxy.html的作用?
由于get.html和data.html不在一个域上,所以不能修改location.hash值,于是运用proxy.html,先跳到找个代理页面,然后通过parent.location.hash,也就是修改父亲,让儿子(get.html)也得到响应。
a.com/get.html



4、window.name

这种方法比较巧妙,引用圆心的解释,name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。
具体例子依旧如上,同时也是需要一个代理页面。
a.com/get.html请求b.com/data.html,首先get.html创建一个iframe,src指向data.html,然后监听iframe的onload事件。与此同时,在data.html设置window.name = data;把window.name赋值。然后onload事件后马上把iframe的跳到本地a.com/proxy.html。因此window.name就共享到了src为proxy.html的找个iframe中,接下来,就是同源间获取值的事了。
a.com/get.html



5、 postMessage()

html5的新方法postMessage()优雅地解决了跨域,也十分容易理解。
发送方调用postMessage()内容,接受方监听onmessage接受内容即可。
假设发送方为a.com/send.html,接受方为b.com/receive.html。
a.com/send.html



6、CORS(后台实现)

以上5点都是前端实现的跨域,但是后台参与会让跨域更容易解决,也就是用CORS。
CORS是Cross-Origin Resource Sharing的简称,也就是跨域资源共享。它有多牛逼?之前说JsonP只能get请求,但CORS则可以接受所有类型的http请求,然而CORS只有现代浏览器才支持。
怎样使用?前端只需要发普通ajax请求,注意检测CORS的支持度。引用自蒋宇捷。



与此同时,服务器端只需要设置Access-Control-Allow-Origin头即可。

java中你只需要设置

代码如下:
response.setHeader("Access-Control-Allow-Origin", "*");

为了安全,也可以将*改为特定域名,例如a.com。

下载本文
显示全文
专题