天天看點

SpringBoot+vue前後端分離的跨域問題

近期項目架構更新,前端統一使用vue架構,背景是SpringCloud系列搭建的微服務。前端統一通路的是zuul網關代理到Docker上的服務,在和前端開發人員調試時發現了問題。

最初背景配置的跨域支援為如下:

**
 * 初始化相關配置
 */
@ControllerAdvice
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        ObjectMapper objectMapper = builder.build();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);// 忽略 transient 修飾的屬性
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
        super.configureMessageConverters(converters);
    }

    //這裡配置對前端跨域的支援
    /**
     * 跨域支援
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                .maxAge(3600);
    }
}
           

這樣配置後,在調試階段前端不通過zuul網關直接通路docker上的服務是沒有問題的。

但是,在生産環境中docker上的服務是無法直接通路的,必須通過zuul網關代理,于是問題來了。。。

由于在zuul網關中是需要檢驗使用者的接口通路權限的,使用者在登陸成功後會得到JWT格式的token,然後在之後的所有請求中必須在RequestHeaders中攜帶token,用于後端校驗。

但是,前端vue在header中設定token後并沒有用,背景接收不到這個token。。。。

其實這就是浏覽器在作怪了,因為前端設定了自定義的請求頭,是以在正常請求之前浏覽器會先發送一個OPTIONS方式的請求用于驗證背景是否支援自定義請求頭。

由于後端并沒有設定對OPTIONS方式請求的支援是以拒絕了,知道了問題的原因後我們隻需要在背景的攔截器中加入判斷的代碼:

//如果是OPTIONS方式的請求直接通過
if ("OPTIONS".equals(request.getMethod())){
            return true;
        }
           

這樣背景就可以正常接收到前端攜帶的token了。

繼續閱讀