简介

CORS的全称是跨域资源共享,他是一个基于HTTP-header检测的机制,通过对HTTP-header进行管制,能够实现对跨域资源的权限治理性能。在之前的CORS详解文章中,咱们曾经对CORS有了根本的解释。

本文将会从netty的实现角度,解说如何在netty中实现CORS。

服务端的CORS配置

相熟CORS的敌人应该晓得,CORS所有的操作都是在HTTP协定之上通过管制HTTP头来实现的。所以说如果要在服务器端实现CORS的反对,事实上也是对HTTP协定的头进行各种设置实现的。

为了不便大家的应用,netty提供了一个CorsConfig类,来对立CORS的头设置。

先看下CorsConfig类中定义的属性:

    private final Set<String> origins;    private final boolean anyOrigin;    private final boolean enabled;    private final Set<String> exposeHeaders;    private final boolean allowCredentials;    private final long maxAge;    private final Set<HttpMethod> allowedRequestMethods;    private final Set<String> allowedRequestHeaders;    private final boolean allowNullOrigin;    private final Map<CharSequence, Callable<?>> preflightHeaders;    private final boolean shortCircuit;

这些属性和CORS的HTTP头设置是一一对应的。比如说origins示意的是容许的源,anyOrigin示意容许所有的源。

是和上面的设置对应的:

Origin: <origin>

exposeHeaders是和Access-Control-Expose-Headers一一对应的,示意服务器端容许客户端获取CORS资源的同时可能拜访到的header信息。其格局如下:

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

allowCredentials示意是否开启CORS的权限认证。示意服务器端是否承受客户端带有credentials字段的申请。如果用在preflight申请中,则示意后续的实在申请是否反对credentials,其格局如下:

Access-Control-Allow-Credentials: true

allowedRequestMethods示意拜访资源容许的办法,次要用在preflight request中。其格局如下:

Access-Control-Allow-Methods: <method>[, <method>]*

allowedRequestHeaders用在preflight request中,示意真正可能被用来做申请的header字段,其格局如下:

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

当客户端发送OPTIONS办法给服务器的时候,为了平安起见,因为服务器并不一定可能承受这些OPTIONS的办法,所以客户端须要首先发送一个
preflighted requests,期待服务器响应,等服务器确认之后,再发送实在的申请。咱们举一个例子。preflightHeaders示意的就是服务器容许额preflight的申请头。

shortCircuit示意申请是否是一个无效的CORS申请,如果申请被回绝之后,就会返回一个true。

CorsConfigBuilder

CorsConfig应用来示意Cors的配置类,那么怎么去结构这个配置类呢?咱们看下CorsConfig的构造函数:

    CorsConfig(final CorsConfigBuilder builder) {        origins = new LinkedHashSet<String>(builder.origins);        anyOrigin = builder.anyOrigin;        enabled = builder.enabled;        exposeHeaders = builder.exposeHeaders;        allowCredentials = builder.allowCredentials;        maxAge = builder.maxAge;        allowedRequestMethods = builder.requestMethods;        allowedRequestHeaders = builder.requestHeaders;        allowNullOrigin = builder.allowNullOrigin;        preflightHeaders = builder.preflightHeaders;        shortCircuit = builder.shortCircuit;    }

能够看到CorsConfig是通过CorsConfigBuilder来结构的。通过设置CorsConfigBuilder中的各种属性即可。CorsConfigBuilder中提供了多种设置属性的办法。

能够应用这样的办法来结构CorsConfig如下:

CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();

CorsHandler

有了corsConfig,咱们还须要将这个config配置在netty的handler中,netty提供了一个CorsHandler类来专门解决corsConfig,这个类就叫CorsHandler。

首先看下CorsHandler的构造函数:

    public CorsHandler(final CorsConfig config) {        this(Collections.singletonList(checkNotNull(config, "config")), config.isShortCircuit());    }    public CorsHandler(final List<CorsConfig> configList, boolean isShortCircuit) {        checkNonEmpty(configList, "configList");        this.configList = configList;        this.isShortCircuit = isShortCircuit;    }

CorsHandler有两个构造函数,一个是传入CorsConfig,一个是传入一个CorsConfig的列表。

CorsHandler的次要工作原理就是在channelRead的时候,对responseHeader进行解决,设置CORS头。

netty对cors的反对

下面咱们曾经讲过了netty中cors的外围类和办法,最初一步就是把cors的反对类退出到netty的pipeline中,其外围代码如下:

    public void initChannel(SocketChannel ch) {        ChannelPipeline pipeline = ch.pipeline();        pipeline.addLast(new HttpResponseEncoder());        pipeline.addLast(new HttpRequestDecoder());        pipeline.addLast(new HttpObjectAggregator(65536));        pipeline.addLast(new ChunkedWriteHandler());        CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();        pipeline.addLast(new CorsHandler(corsConfig));        pipeline.addLast(new CustResponseHandler());    }

总结

cors比较简单,netty也为其提供了住够的办法反对。大家能够间接应用。

本文的例子能够参考:learn-netty4

本文已收录于 http://www.flydean.com/22-netty-cors/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!