你的位置:首页 > 软件开发 > Java > js跨域

js跨域

发布时间:2017-09-20 17:00:05
第一次写博客,好紧张,不知道能写成啥样,哈哈哈。自己的一知片解,有错请多多指教,嘻嘻嘻。一、何为跨域?只要协议、域名、端口后任何一个不同,就是跨域。举个例子:协议不同https://www.example.com域名不同端口不同以下,test1代表www.test1.myhost ...

 第一次写博客,好紧张,不知道能写成啥样,哈哈哈。

自己的一知片解,有错请多多指教,嘻嘻嘻。

一、何为跨域?

只要协议、域名、端口后任何一个不同,就是跨域。

举个例子:

协议不同
https://www.example.com
域名不同
端口不同

以下,test1代表www.test1.myhost.com; test2代表www.test2.myhost.com

1.cookie

存在这样一种情况能够实现共享cookie:两个网页一级域名形同,二级域名不同,设置cookie时,指定两个网页的domain相同,便可以共享cookie啦。

test1:

document.cookie = 'key1= value1; domain=myhost.com';
console.log(document.cookie);//"key1 = value1"

test2:

console.log(document.cookie);//"key1 = value1"

就酱紫,他俩共享cookie了,好可怕

打开application看看,发现这cookie原来在myhost.com域名下。

js跨域

2.iframe

一个页面中嵌套一个iframe,这个iframe的src与主页面跨域。这样的话,主页面获取操作iframe的DOM,iframe也无法操作主页面的DOM

test1为主页面,test2为嵌入的iframe

解决iframe跨域的,宝宝只知道这三种:

(1)片段识别符

(2)window.name

(3)window.postMessage

2.1 片段识别符

指的是URL中#后面的部分,只改变片段识别符,页面不会重新刷新。

实现思路:

父窗口可以把要传递的数据写入iframe的src片段识别符中,iframe通过监听hashchange事件得到通知,获取数据

同样道理,子窗口也可以改变父窗口的片段识别符,达到同样的效果。示例来喽:

父→子:

主页面

var origin = $('iframe').attr('src');$('iframe').attr('src', origin + '#主窗口');

iframe

console.log(window.location.hash);//"#主窗口"

子→父:

iframe

parent.location.href ='http://www.test1.myhost.com:8080/tutor/cookie#iframe'

主页面

console.log(window.location.hash);//"#iframe"

2.2 window.name

浏览器窗口有window.name属性,它的特点是无论是否同源,只要在同一个窗口中,前一个网页设置了这个属性,后一个网页就可以读取它

实现思路:

将iframe需要与主页面传递的数据写到iframe的window.name中,完成后将iframe的src设置成与主页面同源,此时,主页面与iframe就同源了,就可以拿到对方的数据啦,而iframe的src更改并不影响window.name的值啊,主页面便可以轻松读取iframe中window.name的值啦,是不是很机智!再来个例子吧。

iframe

window.name = '哈哈哈,我是iframe';location.href = 'http://www.test1.myhost.com:8080/这里就是一个与主页面同源的页面';

主页面

console.log($('iframe')[0].contentWindow.name);//"哈哈哈,我是iframe"

2.3 window.postMessage

html5引入的新API,允许跨窗口通信,不论这两个窗口是否同源。

window.postMessage(data, url); //data为要传给目标的数据,url为目标的url。

注意,此window是目标窗口的window,不是本窗口的window

同样来个例子:

子→父:

iframe

top.postMessage('hello', 'http://www.test1.myhost.com:8080/tutor/cookie');

主页面

window.addEventListener('message', function(e) { console.log(e.data);//"hello"}, false);

父→子:

主页面

$('.post').on('click', function() { $('iframe')[0].contentWindow.postMessage('hello hello', 'http://www.test2.myhost.com:8080/这里就是一个目标url');});

iframe

window.addEventListener('message', function(e) { console.log(e.data);//"hello hello"}, false);

这里的e有几个重要属性:

a.data:传递来的message

b.source:发送消息的窗口对象

c.origin:发送消息窗口的源(协议+主机+端口号)

3.ajax

诶嘿,宝宝知道的也是三种,哈哈哈,好巧啊

(1)JSONP

(2)websocket

(3)CORS

分别说说吧

3.1 JSONP

原理就是利用script脚本拥有跨域能力。

基本思想是,网页添加一个script元素,src放需要请求的接口,这种做法不受同源策略的限制。服务器收到请求后,将数据放在一个指定的回调函数里传回来。

这种方法简单适用,老式的浏览器全部支持,服务器改造也非常小。

js实现:

function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script);}$('.ajax').on('click', function() { addScriptTag('http://www.php.myhost.com/jsonp.php?callback=foo');});function foo(data) { console.log('response data is: ' + data);};

jQuery实现:

$('.ajax').on('click', function() { $.ajax({ url: 'http://www.php.myhost.com/jsonp.php', type: 'get', dataType: 'jsonp', jsonpCallback: 'foo', data: {} });});function foo(data) { console.log('Your response is: ' + data);};

PHP代码:

<?php$callback = $_GET['callback'];$data = 'hello';echo $callback.'('.json_encode($data).')';?>

3.2 websocket

websocket是一种通信协议。该协议不实行同源策略,只要服务器支持,就可以通过它进行跨源通信。

例如,长连接呀

其实不太懂,就先不说它了哈

3.3 CORS

开始扯啦

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。

CORS请求分为两类:简单请求和非简单请求,太多了,这里就先不介绍了,一查就知道了。

简单请求就是浏览器发出CORS请求时,http头当中增加一个域(origin)的信息。该域包含协议名、地址及一个可选的端口,用来说明本次请求来自哪个源,服务器根据这个值决定是否同意这次请求。(这都是浏览器代为发送,开发者的代码无法触及到)

如果这个指定的源不在许可范围内,服务器就返回一个正常的http回应。但是回应中没有Access-Control-Allow-Origin字段,抛出异常,

如果这个指定的源在许可范围内,会多出几个头信息字段(都以Access-Contrl-开头)

非简单请求(我平常请求的接口都是非简单请求,因为content-type为application/json)是在发起正式通信之前增加一次http查询,实现询问服务器当前网页所在域名是否在许可名单中,得到肯定答复后浏览器才会发出正式的

预检请求的方式是options,头信息里面关键字段是origin,表示来自哪个源。服务器收到预检请求后检查origin,确认是否允许跨源请求,就可以做出回应了。

允许请求:在http回应中,关键是Access-Control-Allow-Origin字段,如:Access-Control-Allow-Origin var xhr = new // 前端设置是否带cookie xhr.withCredentials = true;

jquery

 $.ajax({ xhrFields: {          withCredentials: true // 前端设置是否带cookie     }, });

vue:

vue框架在vue-resource封装的ajax组件中加入以下代码:Vue.http.options.credentials = true

ok ,总算写完啦~~~

哦,对了,加一下ajax跨域的几种现象(这几种现象这个博客说的很好

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:js跨域

关键词:JS

JS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。