Java跨域問(wèn)題的幾種后端解決方式舉例詳解
一、什么是跨域
跨域指的是:瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,從一個(gè)域名的網(wǎng)頁(yè)去請(qǐng)求另一個(gè)域名的資源時(shí),域名、端口、協(xié)議任一不同,都是跨域。跨域是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。a頁(yè)面想獲取b頁(yè)面資源,如果a、b頁(yè)面的協(xié)議、域名、端口、子域名不同,所進(jìn)行的訪問(wèn)行動(dòng)都是跨域的。
二、常見(jiàn)跨域舉例
| 當(dāng)前頁(yè)面URL | 被請(qǐng)求頁(yè)面URL | 是否跨域 | 原因 |
|---|---|---|---|
| http://www.test.com/ | http://www.test.com/index.html | 否 | 同源 (協(xié)議、域名、端口號(hào)相同) |
| http://www.test.com/ | https://www.test.com/index.html | 跨域 | 協(xié)議不同 (http/https) |
| http://www.test.com/ | http://www.baidu.com/ | 跨域 | 域名不同 (test/baidu) |
| http://www.test.com/ | http://blog.test.com/ | 跨域 | 域名不同 (www/blog) |
| http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口號(hào)不同 (8080/7001) |
三、Java后端解決方式
1、實(shí)現(xiàn) WebMvcConfigurer
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 攔截所有的請(qǐng)求
.allowedOrigins("*")// 可跨域的域名,*為所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允許跨域的方法,可以單獨(dú)配置
.maxAge(3600);
}
}
2、實(shí)現(xiàn) HandlerInterceptor
創(chuàng)建一個(gè)類(lèi)實(shí)現(xiàn) HandlerInterceptor 接口,并在 preHandle 方法中設(shè)置響應(yīng)頭以實(shí)現(xiàn)跨域。
@Component
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
return true;
}
// ...
}
```
這將允許來(lái)自 http://example.com 的跨域請(qǐng)求訪問(wèn)應(yīng)用程序中的 API。
3、使用Filter
創(chuàng)建一個(gè)類(lèi)實(shí)現(xiàn) javax.servlet.Filter 接口,并在 doFilter 方法中設(shè)置響應(yīng)頭以實(shí)現(xiàn)跨域。
@WebFilter
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
// ...
}
````
這將允許來(lái)自 http://example.com 的跨域請(qǐng)求訪問(wèn)應(yīng)用程序中的 API。
注意:使用 Filter 實(shí)現(xiàn)跨域時(shí),F(xiàn)ilter 會(huì)攔截所有請(qǐng)求,而不僅僅是跨域請(qǐng)求。因此,在設(shè)置響應(yīng)頭時(shí)需要謹(jǐn)慎,避免影響其他請(qǐng)求的正常處理。如果需要更細(xì)粒度的控制,可以考慮使用 @CrossOrigin 注解或攔截器來(lái)實(shí)現(xiàn)。
4、使用 @CrossOrigin 注解來(lái)實(shí)現(xiàn)
在使用 Spring Boot 實(shí)現(xiàn)跨域時(shí),可以使用 Spring 提供的 @CrossOrigin 注解來(lái)配置跨域訪問(wèn)。具體實(shí)現(xiàn)步驟如下:
(1)在需要實(shí)現(xiàn)跨域的 Controller 類(lèi)或方法上添加 @CrossOrigin 注解。例如:
@CrossOrigin(origins = "http://example.com")
@RestController
public class MyController {
// ...
}
```
這將允許來(lái)自 http://example.com 的跨域請(qǐng)求訪問(wèn) MyController 中的方法。(2)如果需要允許多個(gè)域名訪問(wèn),可以將 origins 參數(shù)設(shè)置為包含所有允許訪問(wèn)的域名的數(shù)組。例如:
@CrossOrigin(origins = {"http://example1.com", "http://example2.com"})
@RestController
public class MyController {
// ...
}
```
(3)如果需要允許跨域的 HTTP 方法不止 GET 和 POST,可以使用 methods 參數(shù)指定允許的方法列表。例如:
@CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})
@RestController
public class MyController {
// ...
}
```
(4)如果需要允許跨域的請(qǐng)求頭不止 Content-Type,可以使用 allowedHeaders 參數(shù)指定允許的請(qǐng)求頭列表。例如:
@CrossOrigin(origins = "http://example.com", allowedHeaders = {"Content-Type", "Authorization"})
@RestController
public class MyController {
// ...
}
```
(5)如果需要允許發(fā)送身份驗(yàn)證信息,可以使用 allowCredentials 參數(shù)將其設(shè)置為 true。例如:
@CrossOrigin(origins = "http://example.com", allowCredentials = "true")
@RestController
public class MyController {
// ...
}
```
5、在響應(yīng)頭中添加 Access-Control-Allow-Origin 等字段
(1)在響應(yīng)頭中添加 Access-Control-Allow-Origin 字段,允許特定的域名訪問(wèn)。例如,以下代碼將允許 http://example.com 的域名訪問(wèn) API:
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
```
如果希望允許所有域名訪問(wèn) API,可以將值設(shè)置為 *:(2)如果需要允許多個(gè)域名訪問(wèn) API,可以在響應(yīng)頭中添加 Access-Control-Allow-Origin 字段,并將其設(shè)置為包含所有允許訪問(wèn)的域名的列表。例如:
response.setHeader("Access-Control-Allow-Origin", "http://example1.com, http://example2.com");
```
(3)如果需要允許跨域的 HTTP 方法不止 GET 和 POST,可以在響應(yīng)頭中添加 Access-Control-Allow-Methods 字段,指定允許的方法列表。例如:
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
```
(4)如果需要允許跨域的請(qǐng)求頭不止 Content-Type,可以在響應(yīng)頭中添加 Access-Control-Allow-Headers 字段,指定允許的請(qǐng)求頭列表。例如:
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
```
(5)如果使用了帶有身份驗(yàn)證信息的請(qǐng)求,例如帶有 Cookie 的請(qǐng)求,那么需要在響應(yīng)頭中添加 Access-Control-Allow-Credentials 字段,并將其設(shè)置為 true,表示允許發(fā)送身份驗(yàn)證信息。例如:
response.setHeader("Access-Control-Allow-Credentials", "true");
```
最后,需要將這些響應(yīng)頭添加到每個(gè)需要跨域訪問(wèn)的 API 的響應(yīng)中。6、使用 Nginx 配置
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
if ($request_method = 'OPTIONS') {
return 204;
}
}
如果使用了帶有身份驗(yàn)證信息的請(qǐng)求,例如帶有 Cookie 的請(qǐng)求,那么需要將 Access-Control-Allow-Credentials 字段設(shè)置為 true,表示允許發(fā)送身份驗(yàn)證信息。例如:
add_header 'Access-Control-Allow-Credentials' 'true';
如果在 Nginx 的 upstream 中使用了負(fù)載均衡,需要在負(fù)載均衡的服務(wù)器塊中添加以上配置。如果使用了反向代理,也需要在反向代理的服務(wù)器塊中添加以上配置。
7、配置 Gateway 的路由
- id: my_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- AddResponseHeader=Access-Control-Allow-Origin:http://example.com
- AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
- AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
- AddResponseHeader=Access-Control-Allow-Credentials:true
`````
這將允許來(lái)自 http://example.com 的跨域請(qǐng)求訪問(wèn) Gateway 中的 API。
如果使用了帶有身份驗(yàn)證信息的請(qǐng)求,例如帶有 Cookie 的請(qǐng)求,那么需要將 Access-Control-Allow-Credentials 字段設(shè)置為 true,表示允許發(fā)送身份驗(yàn)證信息。例如:
- AddResponseHeader=Access-Control-Allow-Credentials:true ````` 最后,需要將這些配置添加到每個(gè)需要跨域訪問(wèn)的 API 的路由配置中。 需要注意的是,如果在 Gateway 的路由中使用了負(fù)載均衡,需要在負(fù)載均衡的路由配置中添加以上配置。如果使用了反向代理,也需要在反向代理的路由配置中添加以上配置。
總結(jié)
到此這篇關(guān)于Java跨域問(wèn)題的幾種后端解決方式的文章就介紹到這了,更多相關(guān)Java跨域問(wèn)題后端解決內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot創(chuàng)建項(xiàng)目包依賴問(wèn)題的解決
本篇文章主要介紹了spring boot創(chuàng)建項(xiàng)目包依賴問(wèn)題的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
SpringSecurit鹽值加密的密碼驗(yàn)證以及強(qiáng)密碼驗(yàn)證過(guò)程
在密碼加密過(guò)程中,鹽值的使用可以增強(qiáng)密碼的安全性,如果忘記存儲(chǔ)鹽值,將無(wú)法驗(yàn)證密碼,強(qiáng)密碼應(yīng)包含數(shù)字、字母和特殊字符,長(zhǎng)度應(yīng)在8到30位之間,以提高賬戶安全2023-03-03
springboot?項(xiàng)目啟動(dòng)后無(wú)日志輸出直接結(jié)束的解決
這篇文章主要介紹了springboot?項(xiàng)目啟動(dòng)后無(wú)日志輸出直接結(jié)束的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Java8 Stream中對(duì)集合數(shù)據(jù)進(jìn)行快速匹配和賦值的代碼示例
這篇文章主要介紹了Java8 Stream中如何對(duì)集合數(shù)據(jù)進(jìn)行快速匹配和賦值,文中通過(guò)代碼示例為大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-06-06
Java實(shí)體類(lèi)(entity)作用說(shuō)明
這篇文章主要介紹了Java實(shí)體類(lèi)(entity)作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
提升java開(kāi)發(fā)效率工具lombok使用爭(zhēng)議
這篇文章主要介紹了提升java開(kāi)發(fā)效率工具lombok使用爭(zhēng)議到底該不該使用的分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
java+selenium實(shí)現(xiàn)滑塊驗(yàn)證
現(xiàn)在越來(lái)越多的網(wǎng)站都使用采用滑塊驗(yàn)證來(lái)作為驗(yàn)證機(jī)制,用于判斷用戶是否為人類(lèi)而不是機(jī)器人,本文就將利用java和selenium實(shí)現(xiàn)滑塊驗(yàn)證,希望對(duì)大家有所幫助2023-12-12

