同源与跨域

1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。

所谓"同源"指的是"三个相同":协议相同、域名相同、端口相同。
本域脚本只能读写本域内的资源,而无法访问其它域的资源。这种安全限制称为同源策略。
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

同源策略的限制:

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求在浏览器端有跨域限制

虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域 。

1.jsonp( 无兼容性问题 )
script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件。类似的还有img和link标签:

<!--不受同源策略限制的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>
<script type="text/javascript">
     var messagetow = function(data){
          alert(data);
     };
     var url = "http://192.168.31.137/train/test/jsonpthree?callback=messagetow";
     var script = document.createElement('script'); 
     script.setAttribute('src', url); 
     document.getElementsByTagName('head')[0].appendChild(script);
 </script>
  1. jsonp的原理就是 借助了script标签 src 请求资源时, 不受同源策略的限制.
  2. 在服务端返回一个函数的调用,将数据当前调用函数的实参。
  3. 在浏览器端,需要程序要声明一个全局函数,通过形参就可以获取到服务端返回的对应的值

jquery对于jsonp的封装

//使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。

$.ajax({
  type:"get",
  url:"http://www.Jepson.com/testjs.php",
  dataType:"jsonp",
  data:{
    uname:"Jepson",
    upass:"123456"
  },
  success:function (info) {
    console.log(info);
  }
});

2.XMLHttpRequest2.0
新版本的功能:

  1. 可以设置timeout超时时间
  2. 可以使用formData对象管理表单数据
  3. 允许请求不同域名下的数据(跨域)
  4. 支持上传二进制文件
  5. 可以获取数据传输的进度信息

新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称CORS) ( 兼容性IE10+ )。
跨域资源共享(CORS)的前提:

  • 浏览器支持这个功能( 兼容性IE10+ )
  • 服务器必须允许这种跨域。

服务器允许跨域的代码:

//允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");
//允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");
@Override
    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.addHeader("Access-Control-Allow-Origin","*");
        response.addHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers","x-requested-with");
        response.addHeader("Access-Control-Max-Age","1800");//30 min
        chain.doFilter(req, res);
    }

CORS的具体流程

  1. 浏览器发送跨域请求
  2. 服务器端收到一个跨域请求后,在响应头中添加Access-Control-Allow-Origin Header资源权限配置。发送响应
  3. 浏览器收到响应后,查看是否设置了header(‘Access-Control-Allow-Origin:请求源域名或者*’);
  4. 如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

结论:

  1. 跨域行为是浏览器行为,响应是回来了的, 只是浏览器安全机制做了限制, 对于跨域响应内容进行了忽略。
  2. 服务器与服务器之间是不存在跨域的问题的。

jsonp与cors的对比:

  1. jsonp兼容性好,老版本浏览器也支持,但是jsonp仅支持get请求,发送的数据量有限。使用麻烦
  2. cors需要浏览器支持cors功能才行。但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的get、post请求并没有什么区别。
  3. 跨域的安全性问题:因为跨域是需要服务端配合控制的 ,也就是说不论jsonp还是cors,如果没有服务端的允许,浏览器是没法做到跨域的。

3.iframe
元素会创建包含另外一个文档的内联框架(即行内框架)。
基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com 这种特点,也就是两个页面必须属于一个基础域(例如都是xxx.com),使用同一协议和同一端口,这样在两个页面中同时添加document.domain,就可以实现父页面调用子页面的函数。

在a.html中:

 <script type="text/javascript">
      document.domain = 'study.cn';
       function test() {
         alert(document.getElementById('a').contentWindow);
       }
 </script>
 <body>
     <iframe id='a' src='http://b.study.cn/b.html' onload='test()'>
 </body>

在b.html中:

<script type="text/javascript">
  document.domain = 'study.cn';
</script>
<body>
   我是b.study.cn的body
</body>

这样就可以通过js访问到iframe中的各种属性和对象了,但是如果你想在http://a.study.cn/a.html页面中通过ajax直接请求页面http://b.study.cn/b.html,即使你设置了相同的document.domain也还是不行的,所以修改document.domain的方法只适用于不同子域的框架(父类与子类)间的交互。

4.代理
如vue-cli项目中的config/index.js文件中的proxyTable设置所要跨域访问的地址。
在这里插入图片描述

5.配置浏览器参数
这里以Google Chrome为例,鼠标右击选择属性在目标框中路径后面添加(注意空格)保存: --args --disable-web-security --user-data-dir
在这里插入图片描述
6.nginx作为网关入口
统一域名端口:

server {
        listen       80;
        server_name  www.test.com;
 
		###A项目
        location /a {
            proxy_pass   http://a.test.com:8080/;
            index  index.html index.htm;
        }
		###B项目
		 location /b {
            proxy_pass   http://b.test.com:8081/;
            index  index.html index.htm;
        }
    }

7.微服务中使用zuul
使用SpringCloud Zuul搭建API接口网关(原理就是统一入口)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值