跨域
跨域是什么
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
跨域怎么出现的
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
跨域存在的问题
- 无法读取非同源网页的 Cookie(存放客户信息的东西)、LocalStorage(前面那个东西容量不够用了,IE8添加进来的做本地存储数据的) 和 IndexedDB(浏览器中的nosql,相对于前面二者能够存储更加多的数据)
- 无法接触非同源网页的 DOM
- 无法向非同源地址发送 AJAX 请求
如何解决跨域问题
- 前后端配合:JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个<script>
元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
// 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(res){
// 处理获得的数据
console.log(res.data)
}
</script>
$.ajax({
url: 'http://www.test.com:8080/login',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {}
});
- 纯后端:cors
通过添加响应头,实现对指定域名的跨越。'*'为所有域。具体实践中可以通过过滤器来进行该响应头的添加。springboot中直接注解@CrossOrigin(origins = “xxx”)
/*
* 导入包:import javax.servlet.http.HttpServletResponse;
* 接口参数中定义:HttpServletResponse response
*/
// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");
// 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
response.setHeader("Access-Control-Allow-Credentials", "true");
// 提示OPTIONS预检时,后端需要设置的两个常用自定义头
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
- 纯前端:
在客户端和服务器之间添加一个代理服务器。比如用nginx做反向代理。通过nginx对请求匹配并发送到相对用的服务器上。由页面请求本域名的一个地址,转由nginx代理处理后返回结果给页面.使用nginx还可以做负载均衡等东西。