学习笔记一一关于跨域

一、什么的是同源?

这是最初由Netscape提出的安全策略,这个策略是为了防止页面使用恶意的方法获取到另一个页面上的敏感信息。所有现代浏览器都会有这个策略。
如果请求数据时浏览器发现请求地址不同源,那么将会不允许这次的请求,报出一个错误。

url描述
上图是一个标准的url连接。
有一些还会带有查询(query)、信息片段(fragment),这里不做讨论;而所谓同源,就是通信协议、主机名、端口号必须相同。

例:

将下面的URL和https://www.kekeke.com:80/panda做对比

url结果原因
https://www.kekeke.com:80/cat同源通信协议、主机名、端口号都相同
http://www.kekeke.com:80/cat不同源通信协议不同(变成http)
https://www.yyy.com:80/cat不同源主机名不同
https://www.kekeke.com:2410/cat不同源端口号不同

只要通信协议、主机名、端口号任意一个不相同,即是不同源。

二、什么是跨域

当我们想通过在自己的网站上获取另一个网站上的数据时,就会造成跨域。比如我在https://www.kekeke.com:80/panda的页面请求https://www.yyy.com:80/cat里的内容,就造成了跨域。浏览器就会不允许我们这么做

三、解决方法

1、JSONP

先来看看定义:JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说,https://www.kekeke.com:80/panda无法与https://www.yyy.com:80/cat的服务器作沟通的,但html标签中的<script></script>是一个例外。

用法:
我们以请求一个豆瓣api接口https://api.douban.com/v2/book/1220562为例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script>
        function doubanCall(data){
            console.log(data)
        }
    </script>
    <script src='https://api.douban.com/v2/book/1220562?callback=doubanCall'></script>
</head>
<body>

</body>
</html>

返回数据如下:
jsonp返回数据
当然doubanCall函数也被执行了:
callbackConsole
jsonp的原理就是利用script标签可以不同源的特性,利用script标签存储返回的数据,然后通过JavaScript的代码来进行调用,当然这个方法也可以返回代码,而且还会被JavaScript解析引擎马上执行。
后面加了?callback=doubanCall是因为一般的jsonp也像其他请求一样,需要后端的配合,后端需要帮我们把数据传入指定的函数(比如callback)后进行返回,下面是我写的一个php小模拟,data表示要返回的数据

<?php

$fn = $_GET['callback'];
echo $fn.'(data)';

使用jQuery和angular等能在实际应用中帮我们更方便的使用jsonp,这个就不详解了。

2、使用window.name属性

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

例:
先看下第一个页面的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script>
        window.onload = function(){
            window.name = '我是第一个页面的window.name属性'
        }
    </script>
</head>
<body>
    <a href="https://www.taobao.com/">转到淘宝</a>
</body>
</html>

打开第一个页面点击a标签后,在淘宝上查询window.name会显示如下:
window.name

window.name在你保持这个窗口的时候,无论在这个窗口打开什么网页,都可以共享这个属性,但这个属性只能以字符串的形式出现,如果设置为其他类型,则会返回一个空字符串或者转换成字符串;而且它最多能保存2M左右的的数据,不同的浏览器可能有所不同。

3、使用CORS

新版本的XMLHttpRequest level 2对象,可以向不同域名的服务器发出HTTP请求。这叫做”跨域资源共享”(Cross-origin resource sharing,简称CORS),CORS就是使用自定义的http头部,让浏览器和服务器进行沟通。当然,想要使用这个功能,是浏览器必须支持,也需要后端的配合。

我们想用这方法来跨域则需要在修改下后端代码,这里以PHP为例:

//下面设置Access-Control-Allow-Origin属性,代表可以允许其他域名访问,
header('Access-Control-Allow-Origin:*');


$money = $_GET['money'];
if ($money > 100){
    echo "服务器给数据了";
}else{
    echo  "没给钱,或钱给的不够";
}

如果需要指定某几个域名才能访问,则需要把Access-Control-Allow-Origin后面的星号(*)改为指定的网址就可以。

这是JS代码:

<script>
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4 && xhr.status == 200){
                console.log('有返回数据,跨域成功,嘤嘤嘤!_____' + xhr.responseText);

            }
        }
        xhr.open('GET','http://localhost/ng-01/get.php?money=101',true);
        xhr.send();

    </script>

返回结果如下:
CORS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值