首頁  >  文章  >  Java  >  springboot如何解決跨域問題?

springboot如何解決跨域問題?

不言
不言轉載
2019-03-19 10:17:386007瀏覽

這篇文章帶給大家的內容是關於springboot如何解決跨域問題?有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

一、什麼是跨域HTTP請求

現代瀏覽器出於安全的考慮,使用XMLHttpRequest物件發起HTTP請求時必須遵守同源策略,否則就是跨域的HTTP請求,預設是被禁止的。跨域HTTP請求是指A域上資源請求了B域上的資源,舉例而言,部署在A機器上Nginx上的js程式碼透過ajax請求了部署在B機器Tomcat上的RESTful介面。 (建議:Java影片教學

IP(網域)不同、或連接埠不同,都會造成跨域問題。為了解決跨域的問題,曾經出現過jsonp、代理檔案等方案,應用場景受限,維護成本高,直到HTML5帶來了CORS協定。

CORS是一個W3C標準,全名為」跨網域資源共享」(Cross-origin resource sharing),允許瀏覽器向跨來源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。它透過伺服器增加一個特殊的Header[Access-Control-Allow-Origin]來告訴客戶端跨域的限制,如果瀏覽器支援CORS、並且判斷Origin通過的話,就會允許XMLHttpRequest發起跨域請求。

CROS常見header

Access-Control-Allow-Origin:http://somehost.com 表示允許http://somehost.com發起跨網域請求。
Access-Control-Max-Age:86400 表示在86400秒內不需要再發送預校驗請求。
Access-Control-Allow-Methods: GET,POST,PUT,DELETE 表示允許跨域請求的方法。
Access-Control-Allow-Headers: content-type 表示允許跨域請求包含content-type

#二、CORS實作跨網域存取

授權方式
方式1:傳回新的CorsFilter
方式2:重寫WebMvcConfigurer
方式3:使用註解(@CrossOrigin)
方式4:手動設定回應頭(HttpServletResponse )

#註:方式1和方式2屬於全域CORS配置,方式3和方式4屬於局部CORS配置。如果使用了局部跨域是會覆蓋全域跨域的規則,所以可以透過@CrossOrigin註解來進行細粒度更高的跨域資源控制。

1.傳回新的CorsFilter(全域跨域)

package com.hehe.yyweb.config;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
          //放行哪些原始域
          config.addAllowedOrigin("*");
          //是否发送Cookie信息
          config.setAllowCredentials(true);
          //放行哪些原始域(请求方式)
          config.addAllowedMethod("*");
          //放行哪些原始域(头部信息)
          config.addAllowedHeader("*");
          //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
          config.addExposedHeader("*");

        //2.添加映射路径
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

#2. 重寫WebMvcConfigurer(全域跨域)

#任意組態類,返回一個新的WebMvcConfigurer Bean,並重寫其提供的跨域請求處理的接口,目的是添加映射路徑和具體的CORS配置資訊。

package com.hehe.yyweb.config;

@Configuration
public class GlobalCorsConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            //重写父类提供的跨域请求处理的接口
            public void addCorsMappings(CorsRegistry registry) {
                //添加映射路径
                registry.addMapping("/**")
                        //放行哪些原始域
                        .allowedOrigins("*")
                        //是否发送Cookie信息
                        .allowCredentials(true)
                        //放行哪些原始域(请求方式)
                        .allowedMethods("GET","POST", "PUT", "DELETE")
                        //放行哪些原始域(头部信息)
                        .allowedHeaders("*")
                        //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                        .exposedHeaders("Header1", "Header2");
            }
        };
    }
}

3. 使用註解(局部跨域)

在方法上(@RequestMapping)使用註解@CrossOrigin :

@RequestMapping("/hello")
@ResponseBody
@CrossOrigin("http://localhost:8080") 
public String index( ){
    return "Hello World";
}

或在控制器(@Controller)上使用註解@CrossOrigin :

@Controller
@CrossOrigin(origins = "http://xx-domain.com", maxAge = 3600)
public class AccountController {

    @RequestMapping("/hello")
    @ResponseBody
    public String index( ){
        return "Hello World";
    }
}
  1. 手動設定回應頭(局部跨域)

使用HttpServletResponse物件新增回應頭(Access-Control-Allow-Origin)來授權原始域,這裡Origin的值也可以設定為"*" ,表示全部放行。

@RequestMapping("/hello")
@ResponseBody
public String index(HttpServletResponse response){
    response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
    return "Hello World";
}

三、測試跨域存取

首先使用Spring Initializr  快速建立一個Maven工程,什麼都不需要改,在static目錄下,新增一個頁面:index.html 模擬跨域訪問。目標位址: http://localhost:8090/hello

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Page Index</title>
</head>
<body>
<h2>前台系统</h2>
<p id="info"></p>
</body>
<script src="webjars/jquery/3.2.1/jquery.js"></script>
<script>
    $.ajax({
        url: 'http://localhost:8090/hello',
        type: "POST",
        xhrFields: {
           withCredentials: true //允许跨域认证
        },
        success: function (data) {
            $("#info").html("跨域访问成功:"+data);
        },
        error: function (data) {
            $("#info").html("跨域失败!!");
        }
    })
</script>
</html>

然後建立另一個工程,在Root Package新增Config目錄並建立設定類別來開啟全域CORS。

package com.hehe.yyweb.config;

@Configuration
public class GlobalCorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }
}

接著,簡單寫一個Rest介面 ,並指定應用連接埠為8090。

package com.hehe.yyweb;

@SpringBootApplication
@RestController
public class YyWebApplication {

    @Bean
    public TomcatServletWebServerFactory tomcat() {
        TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory();
        tomcatFactory.setPort(8090); //默认启动8090端口
        return tomcatFactory;
    }

    @RequestMapping("/hello")
    public String index() {
        return "Hello World";
    }

    public static void main(String[] args) {
        SpringApplication.run(YyWebApplication.class, args);
    }
}

最後分別啟動兩個應用,然後在瀏覽器存取:http://localhost:8080/index.html ,可以正常接收JSON數據,說明跨網域存取成功! !


以上是springboot如何解決跨域問題?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除