zoukankan      html  css  js  c++  java
  • js 跨域复习 window.name | window.domain | iframe | Jsonp

    引起跨域的原因:

    浏览器的同源策略,但是当你要发送请求的时候,出于安全性问题,浏览器有严格的要求,必须协议,域名,端口都相同,这个就是同源策略。

    影响:a通过js脚本向b发送ajax请求,不同源就会报错

    不受影响:script标签,img标签等外部资源引用,重定向,表单提交都不受影响

    ****iframe遇到的跨域问题****

    情况一、假设有a.com/main.html ;  a.com/b.html

    这种情况是涉及不到跨域的

    main.html代码:

    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<div class="box">
    		<iframe id="if" src="b.html" frameborder="0"></iframe>
    	</div>
    <script>
        //获取b的数据
        var bdoc = window.frames[0].document;
        //通过bdoc做操作
    </script>
    </body>
    </html>
    

    b.html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<input id="message" type="text" />
    	<script>
                    //获取父窗docuemnt
    		var pdoc = parent.document;
    	</script>
    </body>
    </html>
    

    情况二、假设有a.com/main.html ;  b.a.com/b.html 此时主域相同子域不同

    只需要在两个页面同时显式的设置docuement.domian = “a.com”即可

    情况三、主域不同 假设有页面 a.com/main.html  ;   a.com/blank.html ;   b.com/b.html

    此时可以利用window.name实现消息传递,具体做法如下:

    b.html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<input id="message" type="text" />
    	<script>
             window.name = "我是要传递的消息";
            </script>
    </body>
    </html>
    

    a.html代码:

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div class="box">
            <iframe id="if" src="b.com/b.html" frameborder="0"></iframe>
        </div>
    <script>
        var fr = document.getElementById('if'),
            state = 0;;
            if(window.VBArray){//兼容ie
                fr.onreadystatechange = function(){
                    if(this.readyState == 'complete'){
                        if(state == 1){
                            // 获取数据
                            data = fr.contentWindow.name;
                        }else{
                            state = 1;
                            // 重置iframe窗口的src保证同源
                            fr.src = 'a.com/blank.html';
                        }
                    }
                }
            }else{
                fr.addEventListener('onload',function(){
                    if(state == 1){
                        // 获取数据
                        data = fr.contentWindow.name;
                    }else{
                        state = 1;
                        // 重置iframe窗口的src保证同源
                        fr.src = 'a.com/blank.html';
                    }
                },false);
            }
    </script>
    </body>
    </html>

    注意:window.name最大存储2M,只能存储字符串格式。由于此方法会重新加载空页面作为iframe的源,所以只适用于隐藏iframe的情况

    ****还有一种方式通过document.hash****

    由父窗口修改子窗口的src添加hash,hash就是要传递的数据,修改hash不会导致页面刷新,子窗口通过一个定时器,定时检测hash是否变化,从而获取父窗口给的数据。

    *****Jsonp跨域****

    jsonp跨域原理:假设有a.com/a.html ;

    ,原理:动态创建script标签,利用script标签src不受同源策略影响

    在页面定义处理数据的函数,参数就是要处理的数据,有后台返回一段js代码,这段代码必须调用a重定义的函数,将返回数据放在参数里

    a.com/a.html代码:

    funciton dealData(data){
    //处理数据
    }
    var script = document.createElement("script"); script.src = "https://b.com/ask?data=1&callback=dealData"; document.body.insertBefore(script, document.body.firstChild);

    此时后台返回的不是一般意义上的数据,而是一段script代码,这段代码调用我们的回调函数  

    由于是通过src来发出请求的,所以jsonp只能是get请求

    ****利用h5的api postMessage跨域****

    假设有a.com/main.html ;  b.a.com/b.html 

    这种方法一方通过postMessage向另一方发送消息,另一方通过onmessage事件获取到消息

    postMessage(发送消息内容,发送目的地)

    onmessage事件通过event.data获取消息

    详细语法可以参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

    a.com/main.html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    	<style>
    		.box{800px;height:400px;background:#ccc;}
    	</style>
    </head>
    <body>
    	<div class="box">
    		<iframe id="if" src="message.html" frameborder="0"></iframe>
    	</div>
    	<script>
    	window.onload = function(){
    		window.frames[0].postMessage('parent','http://b.com/b.html');
    	}
    
    	window.addEventListener('message',function(e){
            var color=e.data;
            console.log(color)
        },false);
    
    	</script>
    </body>
    </html>
    

    b.html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<input id="message" type="text" />
    	<script>
    	document.getElementById('message').value=111;
    	window.addEventListener('message',function(e){
    		alert(1)
    		console.log(e.data);
    		document.getElementById('message').value=e.data;
    		window.parent.postMessage(e.data,'*');
    	},false);
    
    	</script>
    </body>
    </html>
    

    ****利用Cors跨域,这个方式需要后台配合设置header****

  • 相关阅读:
    1225. 岛的周长
    238. Product of Array Except Self除自身以外数组的乘积
    RxJava--Buffer,GroupBy 对比
    RxJava--Buffer,GroupBy 对比
    HDU-2182-Frog
    HDU-2182-Frog
    Linux下必知必会文件和目录
    Linux下必知必会文件和目录
    获取一篇新闻的全部信息
    获取一篇新闻的全部信息
  • 原文地址:https://www.cnblogs.com/youzhuxiaoyao/p/8630433.html
Copyright © 2011-2022 走看看