跨域是什么?
假设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",function(data){
console.log(data.msg);
});
假设上述请求访问b.com下的servlet页面,传的参数为callback="codetitle">复制代码 代码如下:
//dataServlet.java
String callback = req.getParameter("callback");
PrintWriter out = resp.getWriter();
out.print(callback+"('msg','tqtan')");
这样就能成功获取非同源服务器的数据了。
2、$.ajax()
实现原理和上面一样,只是可以自定义更多链接。
$.ajax({ url:'http://b.com/dataServlet"htmlcode">//get.html var iframe = document.creatElement("iframe"); iframe.src="/UploadFiles/2021-04-02/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
var iframe = document.createElement('iframe'); iframe.src = 'http://a.com/get.html#data'; iframe.style.display = 'none'; document.body.appendChild(iframe); //周期检测hash更新 function getHash() { var data = location.hash "from a.com:"+data); var msg = "hello i am b.com"; var iframe = document.createElement('iframe'); iframe.src = "http://a.com/proxy.html#"+msg; iframe.style.display = 'none'; document.body.appendChild(iframe); }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
var state = 0, iframe = document.createElement('iframe'), iframe.src = 'http://b.com/data.html"; iframe.style.display = 'none'; loadfn = function() { if (state === 1) { var data = iframe.contentWindow.name; console.log(data); } else if (state === 0) { state = 1; //跳到proxy.html iframe.contentWindow.location = "http://a.com/proxy.html"; } }; if (iframe.attachEvent) { iframe.attachEvent('onload', loadfn); } else { iframe.onload = loadfn; } document.body.appendChild(iframe); a.com/proxy.html // proxy.html的操作主要是删除get.html的iframe,避免安全问题发生 iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); b.com/data.html var data = "hello,tqtan"; window.name = data;5、 postMessage()
html5的新方法postMessage()优雅地解决了跨域,也十分容易理解。
发送方调用postMessage()内容,接受方监听onmessage接受内容即可。
假设发送方为a.com/send.html,接受方为b.com/receive.html。
a.com/send.html
var iframe = document.createElement("iframe"); iframe.src = "http://b.com/receive.html"; document.body.appendChild(iframe); iframe.contentWindow.postMessage("hello","http://b.com"); b.com/receive.html window.addEventListener('message', function(event){ // 通过origin属性判断消息来源地址 if (event.origin == 'http://a.com') { console.log(event.data); console.log(event.source);//发送源的window值 } }, false);6、CORS(后台实现)
以上5点都是前端实现的跨域,但是后台参与会让跨域更容易解决,也就是用CORS。
CORS是Cross-Origin Resource Sharing的简称,也就是跨域资源共享。它有多牛逼?之前说JsonP只能get请求,但CORS则可以接受所有类型的http请求,然而CORS只有现代浏览器才支持。
怎样使用?前端只需要发普通ajax请求,注意检测CORS的支持度。引用自蒋宇捷。
function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { // 此时即支持CORS的情况 // 检查XMLHttpRequest对象是否有“withCredentials”属性 // “withCredentials”仅存在于XMLHTTPRequest2对象里 xhr.open(method, url, true); } else if (typeof!= "undefined") { // 否则检查是否支持XDomainRequest,IE8和IE9支持 // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式 xhr = new XDomainRequest(); xhr.open(method, url); } else { // 否则,浏览器不支持CORS xhr = null; } return xhr; } var xhr = createCORSRequest('GET', url); if (!xhr) { throw new Error('CORS not supported'); }与此同时,服务器端只需要设置Access-Control-Allow-Origin头即可。
java中你只需要设置
复制代码 代码如下:
response.setHeader("Access-Control-Allow-Origin", "*");
为了安全,也可以将*改为特定域名,例如a.com。
Javascript,跨域问题
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。