這篇文章帶給大家的內容是關於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"); } }; } }
在方法上(@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"; } }
使用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中文網其他相關文章!