前後端分離跨域問題解決方法

前言

當項目前後分離時,就涉及到跨域問題,最近在用一個前端用vue,後端用springboot的項目,就學了一下跨域問題的解決方法,這裏記一下筆記。什麼是跨域,跨域指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對javascript施加的安全限制。解決方法有很多種,這裏記錄個人能夠理解的幾種。

具體方式

  1. @CrossOrigin註解
    Spring MVC提供了@CrossOrigin註解給方法或controller加註解@CrossOrigin(value="*",allowCredentials=“true”)
    缺點:
    <1>每次發送2次請求,第一次查看是否允許跨域請求,第二次發起get、post等請求。
    <2>如果需要傳遞cookies,需要額外設置allowCredentials=“true”。
    <3>爲開發方便往往設置成" * ",導致所有域名都可以跨域請求。

  2. nginx (engine x)反向代理
    需要下載安裝nginx軟件,打開nginx目錄下conf目錄裏面nginx.conf文件,配置文件內容,可以配置客戶端跨域或服務端跨域,兩種方式解決跨域問題,具體配置百度。
    缺點:
    <1>需要單獨安裝軟件,服務器還好,開發時就不方便了。

  3. springboot設置cors跨域
    CORS(Cross-origin resource sharing-跨源資源共享)允許網頁從其他域向瀏覽器請求額外的資源,例如字體,CSS或來自CDN的靜態圖像。 CORS有助於將來自多個域的網頁內容提供給通常具有相同安全策略的瀏覽器。

有倆種解決方法
第一種:

public class CorsFilter extends OncePerRequestFilter {
    static final String ORIGIN = "Origin";
    protected void doFilterInternal(
        HttpServletRequest request, 
        HttpServletResponse response, 
        FilterChain filterChain) throws ServletException, IOException {
        String origin = request.getHeader(ORIGIN);
        response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "PUT, POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "content-type, authorization");
        if (request.getMethod().equals("OPTIONS"))
            response.setStatus(HttpServletResponse.SC_OK);
        else 
            filterChain.doFilter(request, response);
    }
}
@Bean
public CorsFilter corsFilter() throws Exception {
    return new CorsFilter();
}

http
    .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)
    .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)
    .headers()
    .cacheControl();

第二種:
在springboot啓動main類同級目錄下創建一個配置類,如下:

@Configuration
public class CorsConfig {
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        // 設置你要允許的網站域名,如果全允許則設爲 *
        config.addAllowedOrigin("http://localhost:9527");
        // 如果要限制 HEADER 或 METHOD 請自行更改
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        // 這個順序很重要哦,爲避免麻煩請設置在最前
        bean.setOrder(0);
        return bean;
    }
}

4.springboot整合shiro解決跨域
maven導入

<dependency>
       <groupId>org.apache.shiro</groupId>
       <artifactId>shiro-spring-boot-web-starter</artifactId>
       <version>1.4.0</version>
</dependency>

前後端分離跨域解決方案是採用CORS

//這裏實不實現接口沒有影響
@Configuration
public class WebConfig implements WebMvcConfigurer {
//解決跨域
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration conf = new CorsConfiguration();
        conf.addAllowedHeader("*");
        conf.addAllowedMethod("*");
        conf.addAllowedOrigin("*");
        //允許cookie
        conf.setAllowCredentials(true);
        conf.setMaxAge(3600L);
        conf.addExposedHeader("set-cookie");
        conf.addExposedHeader("access-control-allow-headers");
        conf.addExposedHeader("access-control-allow-methods");
        conf.addExposedHeader("access-control-allow-origin");
        conf.addExposedHeader("access-control-max-age");
        conf.addExposedHeader("X-Frame-Options");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", conf); // 4 對接口配置跨域設置
        return new CorsFilter(source);
    }
}

這種方法具體沒有實測,代碼還不完整,具體用法百度。

後記

記錄的這4中方法中,第1種和第3種的第二種方法親測可用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章