前端开发

浏览器的同源策略与跨域:

2019-05-23  本文已影响45人  机智的老刘明同志

浏览器同源策略:

        浏览器会限制对异源(异域)的资源操作

        所谓同源是指:协议,端口,域名均相同


为什么要有浏览器的同源策略:

        1.用户登录了网银,网银向用户的 cookie 中添加用户标识。

        2.用户浏览了恶意页面,执行了恶意页面中的AJAX 请求代码。

        3.恶意页面向网银发起 AJAX HTTP 请求,请求会默认把网银对应 cookie 也同时发送过去。

        4.网银从发送的 cookie 中提取用户标识,验证用户无误,response 中返回请求数据。此时数据就泄露了。


调用第三方接口是跨域吗?

        算跨域。但是接口提供方做了处理。处理方式是CORS


为什么postman调接口不会跨域而浏览器会 :

        浏览器在真正发送请求前,会先发送一个Options请求嗅探,请求成功后才会发送真实的请求.而postman等工具调用接口时,只是简单的访问一个资源,并不存在资源的相互访问。

        为什么需要发送预检请求?是因为触发了浏览器的安全校验。

        为什么请求会触发安全校验?因为当前请求是一个"复杂请求"。

        为什么我的请求是“复杂的”?

        简单请求:请求方法是GET/HEAD/POST,并且contentType为text/plain、application/x-www-form-urlencoded、multipart/form-data。

        不满足上述条件的视为复杂请求,开发中我们常触发这个条件大多因为我们的请求的contentType设置的是application/json导致的。

        简单请求如果设置了Authentication认证header也会让请求“升级”为复杂请求。


模拟跨域:

        我在localhost:8080下访问http://localhost/test/1.php,因为端口号不同,所以算作跨域(尽管返回200,但是数据是空)

跨域的解决方式:

    1.CORS解决跨域问题

        CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而解决AJAX只能同源使用的限制。

        CORS需要浏览器和服务器同时支持。目前基本上主流的浏览器都支持CORS。所以只要后端服务支持CORS,就能够实现跨域。

        对于简单请求,我们后端直接header('Access-Control-Allow-Origin:*');就可以了

        对于复杂请求

        if    request.method == 'OPTIONS':

        # 告诉浏览器你发的非简单请求(修改了Content-type)我允许了

        response['Access-Control-Allow-Headers'] ='Content-type

        '# 告诉浏览器 你发送PUT请求我也支持

        response['Access-Control-Allow-Methods'] ='PUT, DELETE'

        return response

    2.jsonp:

        利用在页面中创建<script>节点的方法向不同域提交HTTP请求的方法称为JSONP,这项技术可以解决跨域提交Ajax请求的问题。

        缺点:只能允许get

        原生写法:

        vue写法:

    3.document.domain + iframe跨域

    4.window.name + iframe跨域

    5.location.hash + iframe跨域

    6.postMessage跨域

    7.nginx代理跨域

        (1)nginx配置解决iconfont跨域

        浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。

        location/ {add_headerAccess-Control-Allow-Origin *;}

        (2)nginx反向代理接口跨域

        跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。

        实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

    8.Nodejs中间件代理跨域

        node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。

    9.WebSocket协议跨域

        WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。

        原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。


        ModifyHeaders(模拟请求头插件实现跨域)

        下载地址:https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?utm_source=chrome-app-launcher-info-dialog

上一篇下一篇

猜你喜欢

热点阅读