前端网络——跨域

前端网络——跨域

一、什么是跨域

1、跨域是指浏览器不能执行其他网站脚本,它是由浏览器同源策略造成的,是js的安全机制。
2、我们知道,页面本身由协议、域名、端口号等组成,例如:https://www.baidu.com:80。只要协议、域名和端口号三者中有任意一个不同,就算跨域。

跨域发生在哪里?

跨域行为发生在浏览器。

=过程=
在一次请求数据的过程中:
即使发生了跨域,请求亦可以发出;
服务器端可以接收、正常处理并正常返回;
数据返回后,浏览器可以接受到数据;
接收数据后,浏览器发现当前页面的域同请求的域不同,判定为跨域。
代码在等待结果,但是浏览器判定跨域,不会把结果传给代码。
=结束=

虽然发生了跨域,但是确实需要所请求的数据,怎么办呢?

二、解决跨域问题

(一)后端配合进行跨域
1、JSONP方法(本次只使用这个方法解决)
2、后端设置Access-Control-Allow-Origin属性以支持跨域
(二)后端不配合进行跨域
1、iframe方式(但只能显示、不能控制)
2、通过自己的后端代理

三、代码

1、原生js发送ajax
<script>
        var oDiv=document.getElementById('test');
         var xhr=null;//创建一个http请求的对象
        if(window.XMLHttpRequest){
            xhr = new XMLHttpRequest();//常用浏览器带的
        }else{
            xhr=new ActiveXObject("Microsoft.XMLHTTP");//支持IE6
        }
        xhr.open("get","url");
        xhr.onreadystatechange=function(){ 
        //status==200 网络请求,结果都会有一个状态码,来表示这个请求是否正常,2××标识成功,3××标识重定向,4××表示客户端错误,5××表示服务端错误
            if(xhr.readyState==4&&xhr.status==200){//状态4表示请求已完成,已接收到数据
                oDiv.innerText=xhr.responseText;//接受到的数据保存在responseText
                var data=JSON.parse(xhr.responseText);
                console.log(data);
            }
        }
        xhr.send();
</script>
2、JSONP跨域
1、使用方法:
<script>
        //jsonp格式哪里特殊?
        //发送的时候,会带上一个参数callback
        //返回的结果不是json
        //callback的名+(+json+);
        $.ajax({
            url:"http://developer.duyiedu.com/edu/testJsonp",
            type:"get",//请求类型
            dataType:"jsonp",//数据类型
            success:function(data){
                console.log(data);
            }
        });
</script>
2、JSONP原理

script标签身上的src属性是不受同源策略限制的,特征是需要后端配合。script标签有src属性,可以发出跨域请求。虽然可以使用其他域上的资源,但是浏览器会将返回内容作为js代码执行。如果有一个与callback值相同的函数看,则会调用这个函数,打印出其中的内容。
1、判断请求与当前页面的域是否同源,如果同源则发送正常的ajax,不跨域。
2、如果不同源,则生成一个script标签
3、生成一个随机的callback名字,创建一个名为这个的方法。
4、设置script标签src,设置为要请求的接口
5、将callback作为参数拼接在后面
6、后端收到请求后开始准备要返回的数据
7、后端拼接数据,将要返回的数据用callback的值包裹起来
8、返回内容
9、浏览器接收到内容,当作js代码执行
10、执行名为这个的方法,从而获取到了要请求的数据。

<script>
//jsonp原理
    //场景:从一个接口获取一个数据,跨域、接口支持jsonp
    //script标签,有src属性可以发出跨域请求。虽然可以使用其他域的资源,但是浏览器会将返回的内容作为js代码执行。

    var $={
        ajax:function(options){
            var url=options.url;
            var type=options.type;
            var dataType=options.dataType;
            //判断是否同源:协议、域名、端口号
            //获取目标的url的域
            var targetprotocol="";//目标接口的协议
            var targetHost="";//目标接口的host,host是包含域名和端口的
            //如果url不带http,那么访问的一定是相对路径,相对路径一定是同源的。
            if(url.indexOf("http://")==0||url.indexOf("https://")==0){
                var targetUrl=new URL(url);
                targetprotocol=targetUrl.protocol;
                targetHost=targetUrl.host;                
            }else{
                targetprotocol=location.protocol;
                targetHost=location.host;
            }
            //首先判断是否为jsonp,不是jsonp不用做其他判断,直接发送ajax
            if(dataType=='jsonp'){
                //看是否同源
                if(location.protocol==targetprotocol&&location.host==targetHost){
                    //此处省略,因为同源,jsonp会当作普通的ajax请求
                // }
                }else{//不同源
                    //随机生成一个callback;
                    var callback="cb"+Math.floor(Math.random()*1000000);
                    //给window添加callback方法。
                    console.log(callback);
                    window[callback]=options.success;
                    //生成script标签
                    var script=document.createElement('script');
                    
                    if(url.indexOf("?")>0){//表示有参数了
                        script.src=url+"&callback="+callback;
                    }else{
                        script.src=url+"?callback="+callback;
                    }
                    script.id=callback;
                    document.head.appendChild(script);
                }
            }
        }
    }
    $.ajax({
        url:"http://developer.duyiedu.com/edu/testJsonp",
        type:'get',
        dataType:'jsonp',
        success:function(data){
            console.log(data);
        }
    });
</script>

本次就写到这里,各位朋友,多学习,多总结哦!欢迎批评指正,谢谢。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值