被“同源策略”限制的我却想着“跨域”

在今天的内容开始之前需要理解什么是“同源策略”。我不得不拿出 MDN 上的定义:

The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.

「译」同源策略是一种关键的安全机制,可以限制一个文档或者脚本如何被加载,与其它源的资源如何交互。它有助于隔离潜在的安全文档,减少潜在的攻击载体。

通俗地讲,同源策略是一种「安全机制」,定义了如何加载资源。在浏览器输入一个 URL 后,它会发出一个或者多个 HTTP 请求。下面我写了一个 demo:

<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Load</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    <style>
        .bg {
            width: 300px;
        }
    </style>
</head>


<body>
    <div id="app">
        <p>{{ message }}</p>
        <img class="bg" src="http://img4.imgtn.bdimg.com/it/u=2853553659,1775735885&fm=26&gp=0.jpg" alt="" srcset="">
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: '你好前端小课'
            }
        });
</script>
<script>
        $.ajax({
            method: "GET",
            url: "http://192.168.8.210:9999/api/fe/list",
            data: { name: "John", location: "Boston" }
        }).done(function (msg) {
            alert("Data Saved: " + msg);
        });
</script>
</body>


</html>

在Chrome浏览器中加载上面的页面,打开开发者工具可以看到与这个页面相关的所有 HTTP 请求。

总共有 5 个网络请求:

1.webload.html

这个是加载 html 文件需要执行的 HTTP 请求;

2.vue.js

第 8 行代码,使用 script 标签加载 vue.js 文件;

3.jquery.js

第 9 行代码,使用 script 标签加载 jquery.js 文件;

4.u=2853553659,xxxxx

第 20 行代码 img 标签加载的图片;

5.list?name xxxx

第 31 行代码发起的 ajax 请求;

综上,当加载一个页面的时候,与这个页面相关的资源都会通过 HTTP 请求获取。

但是在第 5 个 HTTP 请求的时候,浏览器会报一个错误:

这段代码发起一个 ajax 请求,代码如下:

$.ajax({
    method: "GET",
    url: "http://192.168.8.210:9999/api/fe/list",
    data: { name: "John", location: "Boston" }
}).done(function (msg) {
    alert("Data Saved: " + msg);
});

请求地址为:

http://192.168.8.210:9999/api/fe/list

这个请求与我们访问的页面不在同一「源」,违反了浏览器的同源策略,浏览器为安全起见,不会处理返回的响应。http://192.168.8.210:9999 这个是我们前面写的 HTTP 服务器,我拿来用了一下。

我们的主页面地址是:http://192.168.8.210:8080/webload.html,端口为 8080。

同源策略的条件是需要满足协议、host和端口一致,才属于「同源」,举个例子(图来自 MDN):

但是你可能会发现 请求 vue.js 和 jQuery 也不符合同源策略,但为啥能够获取到数据呢?

这是因为 script、img 和 link 标签比较特殊,它不同被同源策略限制。

这种限制虽然可以避免一些安全攻击,但是在实际应用中会经常遇到跨域访问的情况,例如,用户的网站A(www.a.com)后端使用了BOS存储,用户想在该网站的Web应用程序中引用存储在BOS上的资源,但该页面只能请求本域资源,向BOS发送的请求会被浏览器限制,无法直接访问带来不便。为了解决这类跨域访问问题,HTML5提供了一套标准跨域解决方案即CORS(跨域资源共享)。

跨域是突破同源策略的一种手段,有很多种方法可以实现。大的思路是,既然同源策略是浏览器的限制,那么是否可以绕过浏览器的限制呢?

答案是肯定的,比如移动 web 开发中通常会通过 bridge 的方式使用端的网络请求,获取到数据后再把数据交给前端。前端中也可以通过 node 来进行网络请求。或者使用代理的方式。

其实 Server 可以在响应头中设置 Access-Control-Allow-Origin ,这样浏览器就会正常处理接收到的响应,实现跨域。

res.writeHead(200, {
    'Access-Control-Allow-Origin': '*'
});

总结

同源策略是浏览器的一种安全手段,不到万不得已的时候能不破坏就不要破坏。实现跨域的手段有很多,大体思想就是想方设法符合同源策略的要求。


推荐阅读:

第3天:HTTP 之客户端与服务端

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

https://cloud.baidu.com/doc/BOS/s/djwvys8lg

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值