AORS跨域问题解决
浏览器在访问非本域的请求的时候,会有跨域问题。有跨域的问题后,浏览器中正常的访问会分为两次访问进行:
1.浏览器会先用options请求,返回的header中会有“Access-Control-Allow-Origin”,“Access-Control-Allow-Methods”,“Access-Control-Allow-Headers”,“Access-Control-Max-Age”等值,来确定要访问的域是否支持跨域,以及支持哪种访问类型的跨域。
2.如果返回的header中是支持跨域的,则进行直接的访问。
其中第一次的问询访问只会执行一次,得到允许跨域的信息后,之后的访问会直接进行。在支持跨域的header信息中可以通过Access-Control-Max-Age设置允许跨域的时间,过了这个时间,还会再次进行问询。
在我们springcloud的项目中,使用了swagger配置文件作为api的访问控制配置文件。在swagger-ui的页面中,希望能从页面上直接点击“try it out!”按钮直接检测该接口是否正常,而网关地址和swagger-ui并非同一域,这样就存在了跨域问题。
处理方式:
在zuul网关的“pre”类型的第一个filter中判断请求方法是否是options,并判断请求地址是否是swagger-ui的地址,如果都是,则在request中设置标注,标注该次访问是跨域的问询访问,然后直接跳过后续所有的“pre”类型的filter,在“post”类型的filter中判断该标注,如果是跨域的问询访问,则设置返回头信息和返回状态码
ctx.getResponse().setHeader("Access-Control-Allow-Origin",AORS_Url);
if(ctx.getRequest().getAttribute("aorcOptions")!=null){
String origin = ctx.getRequest().getHeader("Origin");
ctx.getResponse().setHeader("Access-Control-Allow-Headers", "*");
ctx.getResponse().setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
ctx.getResponse().setHeader("Access-Control-Max-Age", "3600");
ctx.setResponseStatusCode(200);
ctx.setResponseDataStream(null);
}
将Access-Control-Allow-Origin设置放在外面,是因为经过问询成功后的正式访问的时候,还是需要判断该头信息是否存在。
因为通过swagger-ui的接口访问只存在于开发环境中,可以在开发环境的配置中增加允许跨域标志,只在开发环境允许跨域,其他环境不允许跨域访问。