跨域

跨域是什么

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。

跨域怎么出现的

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

跨域存在的问题

  1. 无法读取非同源网页的 Cookie(存放客户信息的东西)、LocalStorage(前面那个东西容量不够用了,IE8添加进来的做本地存储数据的) 和 IndexedDB(浏览器中的nosql,相对于前面二者能够存储更加多的数据)
  2. 无法接触非同源网页的 DOM
  3. 无法向非同源地址发送 AJAX 请求

如何解决跨域问题

  1. 前后端配合: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: {}
});
  1. 纯后端: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");
  1. 纯前端:
    在客户端和服务器之间添加一个代理服务器。比如用nginx做反向代理。通过nginx对请求匹配并发送到相对用的服务器上。由页面请求本域名的一个地址,转由nginx代理处理后返回结果给页面.使用nginx还可以做负载均衡等东西。
posted @ 2020-09-15 08:37  大嘤熊  阅读(102)  评论(0编辑  收藏  举报