美文网首页
同源策略

同源策略

作者: _1633_ | 来源:发表于2020-09-22 10:01 被阅读0次

    什么是同源策略

        一个域名地址由 协议、域名、端口、请求资源地址 等部分组成。

    域名地址

        如果两个 URL 的协议、域名和端口都相同,我们就称这两个 URL 同源

        浏览器默认两个相同的源之间是可以相互访问资源和操作 DOM 的。两个不同的源之间若想要相互访问资源或者操作DOM,那么会有⼀套基础的安全策略的制约,我们把这称为 同源策略它的存在可以保护用户隐私信息,防止身份伪造等(读取Cookie)。

        同源策略主要表现在 DOM、web 数据 和 网络 这三个层面。

        但是有三个标签是允许跨域加载资源:

        <img src=’’>

        <link href=‘’>

        <script src=‘’>


        1. DOM

           同源策略限制了来⾃不同源的 JavaScript 脚本对当前 DOM 对象读和写的操作。

            打开两个同源的 网站,我们可以通过控制台 在 某个页面中控制 另外一个页面,比如获取操纵页面的 DOM 结构;对于不同源的网站,它们是 无法相互操作的。

            在实际过程中,我们有时候需要两个不同源的 DOM 之间进行通信(典型的例子是 iframe 窗口和 window.open 方法打开的窗口,它们与父窗口无法通信。),于是浏览器提供了 跨文档消息机制, 可以通过 window.postMessage 的 JavaScript 接口来和不同源的 DOM 进行通信。

            postMessage 方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。

            比如  

            <iframe src="http://localhost:3000/users/reg" id="ifr">

             var frm=document.getElementById("ifr");  

            ifr.contentWindow.postMessage("跨域请求信息","http://localhost:3000");

            接口页

            window.addEventListener("message",(e)=> {}, false);


        2. 数据层面 

            同源策略限制了不同源的站点读取当前站点的Cookie、IndexDB、LocalStorage等数据。由于同源策略,我们依然⽆法通过第⼆个页面 来访问第⼀个页⾯中的Cookie、IndexDB或者LocalStorage等内容。

            想想,如果没有同源策略,那么 我们就可以通过 js 代码, 来获取重要网站的 cookie, input 中 输入的账号密码, 比如 银行网站,那么就会产生严重的后果。


        3. 网络层面

            同源策略限制了通过 XMLHttpRequest 等方式将站点的数据发送给不同源的站点。比如 我们经常遇到的 跨域问题。

            跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。

            之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。

            在实际过程中,我们有时候需要跨源 进行接口请求,比如我们在本地开发请求接口的时候,经常会请求出现跨域,最常用的解决方法就是 跨域资源共享(CORS),使用该机制可以进行跨域访问。

            在 node 中的设置响应头 Access-Control-Allow-Origin 为 指定同源策略的地(请求接口的站点)或者干脆来者不拒 设置为 *,同源策略默认地址是网页的本身。只要浏览器检测到响应头带上了CORS,并且允许的源包括了本网站,那么就不会拦截请求响应


        除了上面 介绍解决跨域的 方法: CORS, postMessage,还有  JSONP、WebSocket。

        但是 JSONP 在实际开发过程中现在 用的比较少, WebSocket 目前没有接触到。

        JSONP 的原理就是 利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。JSONP 仅支持 get 方法具有局限性(JSONP是通过动态创建 script 实现的, 动态创建 script 只能发起 get 请求,无法发起post请求)。

        1 声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。

        2 创建一个<script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=fn)。

        服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是 fn({msg:"this is data"})。

        3 最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。

    JSONP

        Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。这块以后在另外写文章。


        总结

            了解了 同源策略的 意义 和 在实际开发过程中 解决跨域的 方法。

            注意: 跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。

    相关文章

      网友评论

          本文标题:同源策略

          本文链接:https://www.haomeiwen.com/subject/xxujyktx.html