什么是同源
同源策略用于限制页面发起不同域(源)的请求,用于提高请求的安全性。
-
如果两个页面的协议、端口、IP地址(域名)都相同的话,那么这两个页面就是同源,也就是同一个域。
举例:以http://192.168.10.1:8080/index.html为对照源, http://192.168.10.1:8080/auth/login.html与它是同源; http://192.168.10.1:8181/index.html与它不是同源,因为端口不一样; http://192.168.10.30:8080/index.html与它不是同源,因为IP地址不一样。
什么是跨域
- 如果你做了一些前后端分离的项目,由于此时前端所在的服务地址与后端所在的服务地址不一样,你可能会遇到一个请求被浏览器拦截了的问题,浏览器在检测到当前页面发起的请求不属于当前域就会将其拦截,这是因为浏览器的“同源策略”
为什么浏览器会使用同源策略?它想解决什么问题?
首先,先谈一下cookie吧,cookie主要用于存储一些当前网站的一些数据,在一些旧的web开发中有的还会把用户登录信息存储到cookie中。那么,从安全的角度来考虑的话,你应该希望你的网站的cookie不能被另外一个网站使用(不然cookie中的数据就非常容易被别人窃取了),所以这就引入了域的概念,通过域来限制资源的使用,拦截跨域的资源请求。
- 那么我们如何做到跨域呢? 常见的用于解决跨域调用接口的问题就是CORS跨域和JSONP 跨域
CORS 跨域
如何允许跨域,一种解决方法就是目的域告诉请求者允许什么来源域来请求,那么浏览器就会知道B域是否允许A域发起请求。
-
CORS("跨域资源共享"(Cross-origin resource sharing))就是这样一种解决手段。
CORS使得浏览器在向目的域发起请求之前先发起一个OPTIONS方式的请求到目的域获取目的域的信息,比如获取目的域允许什么域来请求的信息。
跨域1.png
此时目的域通常需要在响应头中添加以下信息:
Access-Control-Allow-Origin:用来声明什么域可以向当前域发起请求。
Access-Control-Allow-Methods:用来声明可以向当前域发起什么类型的请求。
Access-Control-Max-Age:用来指定本次OPTIONS请求的有效期,单位为秒,在此期间不用发出另一条OPTIONS请求。
Access-Control-Allow-Headers:用来允许你附加什么特殊的请求头来发起请求。【有些前后端分离项目会把token放到header中,这时候这个请求头就需要Access-Control-Allow-Headers来声明了】
【在OPTIONS请求成功后,浏览器会把这些信息记录下来,用来判断发往目的域的请求是否需要拦截。如果OPTIONS请求失败,那么原本要发起的请求就不会发送。】但有时候发请求是不会触发OPTIONS请求的。如果这个请求符合以下条件的话: 1.请求的方式是GET、POST或HEAD。 2.请求头属于Accept,Accept-Language,Content-Language,Content-Type ,Viewport-Width。 3.请求头中Content-Type属于application/x-www-form-urlencoded、multipart/form-data、text/plain中的一个。 这种请求也被称为“简单请求”。
JSONP 跨域
JSONP原理:
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。
-
具体思路步骤:
例: GK.com访问qq.com qq.com将数据写到 /friend.js GK.com用script标签引用/friend.js GK.com会事先定义好window.yy函数 /friend.js执行window.yy({friends[...]}) 然后GK.com就会通过window.yy拿到数据....
为什么我们要使用JSONP 跨域?
因为我们在跨域时候,由于当前浏览器不支持CORS,或者因为某些原因条件不支持使用CORS时,我们必须使用另外一种方法来跨域。于是我们请求一个js文件,这个文件会执行一个回调,回调里面就有我们的思路。
- 这个回调的名字?
解:回调的名字是可以随机生成的,我们把这个名字以CORS的参数传递给后台,后台会把这个函数返回给我们并执行。
JSONP 跨域的优点缺点?
- 优点: 是可以兼容IE,可以跨域。
- 缺点:
- 由于是script标签,所有它读不到AJAX那么精确状态并且不知道状态码.
- 只能发'GET'请求,不支持'POST'