跨域、CORS、JSONP
同源策略
首先我们来说一说什么是同源
在此之前我们要先知道什么是源
源:
window.origin或者location.origin都可以得到当前源当我们在控制台使用这两个命令之后我们会得到相同的一个网址,这个即使当前网站的源
源 = 协议+域名+端口号
如果两个url的
协议,域名,端口号完全一致,那么我们就说两个url是同源的。
举例:
http://qq.com https://qq.com不同源
https://baidu.com https://baidu.com 不同源
只有完全一致才算同源
同源策略
为了保护用户的隐私,浏览器有这样的规定
如果js运行在源A里面,那么就只能获取到源A的数据,不能获取源B的数据,即不允许跨域
举个例子,
假设baidu.com/index.html 引用了cdn.js,那就说1.js运行在源baidu.com里面,注意这个跟cdn.com没有关系,虽然1.js是从它那里下载的,所以1.js只能在baidu.com里面获取数据,不能获取其他源的数据,
这个是浏览器的功能,主要就是为了保护用户的隐私。
也就是说,不同源之间不能互相访问数据,这就是同源策略
那么如果我们不同源之间想要访问数据怎么办,也就是想要跨域怎么办?
方法一:CORS
CORS
不同源之间想要访问数据,我们就要提前声明,怎么声明呢?
只要在你想访问的源的响应头里面写上xxx源可以访问就可以了具体语法就是:
Access-Control-Allow-Origin:httpp://foo.example
举个例子:
如果你想在https://baidu,com里面访问qq.com里面的数据,那么只需要在qq.com的响应头里面加上
Access-Control-Allow-Origin:httpp://baidu.com
就可以了,这就是CORS,CORS就是这么简单!
但是呢,这里有一个问题,万恶的IE它不支持CORS,所以我们还得去兼容IE,那么IE如何做到跨域呢,用JSONP
JSONP
什么是JSONP呢,IE不支持CORS,但是它支持访问JS,因为JS我们是可以随意的引用的,所以我们只需要将数据放到JS里面就可以访问了,我们虽然不能引用qq.com:8888/friends.json,但是我们能引用qq.com:8888/friends.js啊
具体步骤如下:
-
qq.com将数据写到/friends.js里面
-
baidu.com用script标签引用/friends.js
-
/friends.js执行,执行什么呢
-
baidu.com事先定义好window.xxx函数
-
/friends.js执行window.xxx({friends:[]})
-
然后baidu.com就可以通过window.xxx获取数据了
-
到这里我们会发现window.xxx就是一个回调
到这里我们再说一下什么是JSONP
JSONP就是当浏览器不支持CORS或者某些原因不支持CORS时,我们需要其他的方式来进行跨域,这种方式是我们请求一个js文件,这个js文件里面会执行一个回调,回调里面就有我们的数据,回调的名字可以随机生成。
简单来说JSONP就是创造一个js,这个js里面夹带着数据。
JSONP的优点:
支持IE
可以跨域
缺点:
由于是script标签,所以我们读不到AJAX那么精确的状态,不知道状态码是什么,只有成功和失败,同时因为是script标签,JSONP不支持post,只支持get请求。