美文网首页
前后端分离 跨域

前后端分离 跨域

作者: 阿太哥 | 来源:发表于2017-09-11 23:05 被阅读109次

    前提提示:最近的项目中,采用了前后端分离的开发模式。前端通过fetch api访问后端rest api。其间很自然的就会出现跨域问题。

    什么是跨域?

    以下是脑补之后的一些理解。

    CORS(Cross-origin request sharing)跨域资源共享,是一个w3c标准,它允许你向一个不同源服务发出XMLHttpRequest请求,从而克服ajax只能请求同源服务的限制。

    浏览器出于安全考虑,实施的一种同源策略,对非同源访问会主动拦截掉。

    同源是指具有相同的:url协议(eg:http,https)、域名(eg:google.com)、端口

    在浏览器中,script、img、iframe、link(这些标签似乎都有src属性)等标签可以加载跨域资源,而不受同源限制。

    那么如何处理跨域的请求呢?目前比较多做法是jsonp,nginx反向代理,cors本文主要介绍cors.

    jsonp:通过可以跨域的script标签,这样请求就能跨域访问了,通过约定好回调,就能获得相关响应数据。缺点是只支持GET不支持POST等其它类型请求;

    nginx代理:通过一个代理服务器,转发请求到后端服务。缺点是扩展性不好。开发,测试,预发布等几个环境切换都需要配置。

    cors: 支持所有类型的http请求,在服务端设置即可。缺点是老的浏览器不兼容(IE6,7,8 没关系,这些老版本不要管了)

    CORS基本过程:

    在HttpServertResponse响应中添加响应头:

    Access-Control-Allow-Origin:(必设)添加浏览器允许的域名,可设置*表示任何。(origin是你浏览器上的地址组成的)

    Access-Control-Allow-Credentials:(可设)是否允许发送cookie。如果设置为true,客户端请求也要将withCredentials设为true;

    Access-Control-Request-Method: 必须的,表示CORS上会使用到那些HTTP方法;

    Access-Control-Request-Headers: 必须的,表示CORS上会有那些额外的的有信息;

    SpringBoot支持cors

    SpringBoot中已经很好的支持了cors

    CorsFilter类提供了改功能,通过构造UrlBasedCorsConfigurationSource类相关配置

    以下是基本的代码:

    @Configuration

    public classCorsConfig {

    private CorsConfiguration buildConfig(){

    CorsConfiguration corsConfiguration =newCorsConfiguration();

    corsConfiguration.addAllowedOrigin("*");//允许任何域名

    corsConfiguration.addAllowedHeader("*");//允许任何头

    corsConfiguration.addAllowedMethod("*");//允许任何方法get,post..

    returncorsConfiguration;

    }

    @Bean

    public CorsFiltercors Filter(){

    UrlBasedCorsConfigurationSource source =new UrlBasedCorsConfigurationSource();

    source.registerCorsConfiguration("/**",buildConfig());

    return newCorsFilter(source);

    }}

    至此,一个接受任何域的跨域请求就ok了。

    跨域共享cookie

    但是还未结束,对于权限验证,目前还是使用的基于session,cookie的验证,所以这种方案需要实现跨域共享cookie.(强烈不建议使用cookie),那么对于客户端的请求就需要额外加上几个参数。

    对于跨域共享cookie,需要注意的是后端响应的response head里的 Access-Control-Allow-Origin不能是通配符,且不能配置多个,Access-Control-Allow-Credentials需要设置为true

    对于Access-Control-Allow-Origin的限制,只能指定单一域名或使用req.getHeader("Origin")来获取每次请求的Origin。这样一来,你要另外写一个Filter。

    客户端的设置:以jQuery为例需要在里面加入xhrFields: {withCredentials: true},crossDomain: true 

    在这些修改做好后,访问后端接口,但是依然不能解决。排查了半天,是跨域请求之前都要执行一个OPTIONS请求,这个请求是一个预检测的服务,用于获知服务端能接受哪些请求方法,origin等信息。后端会在响应中返回一个cookie,在下一次请求时会带上这个cookie。就实现了基本的跨域cookie共享,后端也能正常获取到session。

    这个请求可以特殊处理。

    相关文章

      网友评论

          本文标题:前后端分离 跨域

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