介紹
跨域(Cross-Origin)指的是在瀏覽器中,由于安全策略的限制,當(dāng)前網(wǎng)頁的 JavaScript 代碼無法直接訪問不同源(協(xié)議、域名、端口)的資源。這意味著如果網(wǎng)頁嘗試通過 AJAX、Fetch 或 WebSocket 等方式向不同源的服務(wù)器發(fā)送請求,瀏覽器會阻止這些請求,從而避免潛在的安全風(fēng)險。
產(chǎn)生原因
瀏覽器同源策略(Same-Origin Policy)是一種安全機(jī)制,用于限制從一個源加載的文檔或腳本如何與來自其他源的資源進(jìn)行交互。同源策略的目的是保護(hù)用戶隱私和防止惡意代碼的執(zhí)行。
同源策略要求兩個 URL 的協(xié)議、主機(jī)名和端口號必須完全相同,才被認(rèn)為是同源。如果兩個 URL 的協(xié)議、主機(jī)名或端口號之一不同,就會被視為跨源請求,那么在默認(rèn)情況下,瀏覽器會阻止跨源請求的訪問。
同源策略限制了以下幾個方面的跨源行為:
-
DOM 訪問限制:跨源的 JavaScript 無法訪問不同源頁面的 DOM 結(jié)構(gòu)。
-
數(shù)據(jù)訪問限制:跨源的 JavaScript 無法讀取不同源的數(shù)據(jù),如讀取 Cookies、LocalStorage 或發(fā)送 AJAX 請求。
-
腳本執(zhí)行限制:無法加載不同源的 JavaScript 腳本。
為了允許某些跨源行為,瀏覽器提供了一些機(jī)制,如跨域資源共享(CORS)和 JSONP。這些機(jī)制通過特定的頭部字段或動態(tài)創(chuàng)建 script 標(biāo)簽來允許跨源請求。
需要注意的是,同源策略僅在瀏覽器環(huán)境中起作用,對于服務(wù)器端和其他環(huán)境并不適用。服務(wù)器端可以通過其他方式進(jìn)行跨域訪問,如代理服務(wù)器或后端接口配置等。
常見解決方案
跨域限制的原因是瀏覽器的同源策略(Same-Origin Policy),該策略要求網(wǎng)頁只能訪問與其來源相同的資源。但是,有時候我們需要在不同源之間進(jìn)行數(shù)據(jù)交互,這就需要使用跨域解決方案。
- JSONP(JSON with Padding):通過動態(tài)創(chuàng)建
<script>
標(biāo)簽,將跨域請求數(shù)據(jù)封裝在一個回調(diào)函數(shù)中返回,利用<script>
標(biāo)簽的跨域特性實現(xiàn)數(shù)據(jù)獲取。 - CORS(Cross-Origin Resource Sharing):服務(wù)端設(shè)置相應(yīng)的響應(yīng)頭,允許跨域訪問。在服務(wù)端設(shè)置 Access-Control-Allow-Origin 頭部字段,指定允許訪問的域名或通配符 *。
- 代理服務(wù)器:在同源的服務(wù)器上創(chuàng)建一個接口,將客戶端請求發(fā)送到目標(biāo)服務(wù)器,并將響應(yīng)返回給客戶端。客戶端只與同源的服務(wù)器通信,避免了跨域問題。
- WebSocket:使用 WebSocket 進(jìn)行雙向通信時,由于 WebSocket 協(xié)議的特殊性,允許跨域通信。
請注意,這些跨域解決方案各有優(yōu)缺點,選擇適合您需求的解決方案取決于具體情況。同時,為了確保安全性,應(yīng)該仔細(xì)考慮跨域請求所帶來的潛在風(fēng)險,并采取適當(dāng)?shù)陌踩胧?/p>
SpringBoot中CORS跨域解決
在 Spring Boot 中解決跨域問題,你可以使用 Spring 提供的 @CrossOrigin 注解或者通過配置 WebMvcConfigurer 來實現(xiàn)。
- 使用 @CrossOrigin 注解:
在你的控制器類或方法上添加 @CrossOrigin 注解,可以指定允許訪問的源、允許的 HTTP 方法、允許的請求頭等。
@RestController
@CrossOrigin(origins = "http://example.com")
public class MyController {
// ...
}
上面的示例中,允許來自 http://example.com 域名的請求訪問該控制器
- 配置 WebMvcConfigurer:
在你的 Spring Boot 項目中創(chuàng)建一個配置類,實現(xiàn) WebMvcConfigurer 接口,并覆蓋 addCorsMappings 方法,在該方法中配置跨域設(shè)置。
示例:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
}
上面的示例中,配置了允許來自 http://example.com 域名的請求訪問任意路徑,并允許的 HTTP 方法包括 GET、POST、PUT 和 DELETE,允許的請求頭為任意頭部。
- 使用 Filter 進(jìn)行跨域設(shè)置:
創(chuàng)建一個實現(xiàn) javax.servlet.Filter 接口的過濾器類,然后在 doFilter 方法中設(shè)置跨域相關(guān)的響應(yīng)頭。
示例:
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Origin", "http://example.com");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
httpResponse.setHeader("Access-Control-Allow-Headers", "*");
chain.doFilter(request, response);
}
}
然后在你的 Spring Boot 項目中注冊該過濾器,可以通過配置類或者在 web.xml 文件中配置。
- Spring Security 中禁用跨域資源共享(CORS),可以使用以下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().disable() // 禁用 CORS
.and()
// 其他配置項...
}
}
通過在 configure(HttpSecurity http) 方法中調(diào)用 .cors().disable(),可以禁用 Spring Security 的 CORS 配置。這將允許跨域請求的發(fā)生而無需進(jìn)行任何限制。
請注意,在禁用 CORS 后,跨域請求將不受 Spring Security 的限制,這可能會導(dǎo)致安全風(fēng)險。建議在開發(fā)環(huán)境中使用此配置進(jìn)行臨時調(diào)試和測試,而在生產(chǎn)環(huán)境中仔細(xì)考慮跨域請求的安全控制。
- 使用代理服務(wù)器(如 Nginx)進(jìn)行跨域設(shè)置:
如果你的應(yīng)用程序部署在代理服務(wù)器(如 Nginx)后面,你可以通過配置代理服務(wù)器來解決跨域問題。在 Nginx 配置中添加以下內(nèi)容:
location / {
add_header Access-Control-Allow-Origin http://example.com;
add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE;
add_header Access-Control-Allow-Headers *;
proxy_pass http://your-backend-server;
}
上面的示例中,配置了允許來自 http://example.com 域名的請求訪問,并轉(zhuǎn)發(fā)到后端服務(wù)器。
常見跨域http響應(yīng)頭說明
在跨域請求中,常見的響應(yīng)頭配置包括以下幾個:
-
Access-Control-Allow-Origin:指定允許訪問的源(域)列表??梢栽O(shè)置為具體的* 域名,也可以使用通配符 "" 表示允許任意域進(jìn)行訪問。
-
Access-Control-Allow-Methods:指定允許的請求方法。例如,“GET, POST, * PUT, DELETE” 表示允許使用這些方法進(jìn)行請求。*
-
Access-Control-Allow-Headers:指定允許的請求頭信息??梢栽O(shè)置為具體的頭部* 字段,或者使用 "" 表示允許任意頭部字段。
-
Access-Control-Allow-Credentials:指定是否允許發(fā)送身份憑證(如 * cookies、HTTP 認(rèn)證或客戶端 SSL 證書)到跨域請求的目標(biāo)服務(wù)器。如果設(shè)置為 * true,則允許發(fā)送身份憑證;如果設(shè)置為 false,則不允許發(fā)送身份憑證。*
-
Access-Control-Expose-Headers:指定允許瀏覽器訪問的響應(yīng)頭信息。例如,* “Content-Type, Authorization” 表示允許訪問這些響應(yīng)頭。*
-
Access-Control-Max-Age:指定預(yù)檢請求的有效期,即在發(fā)送實際請求前,瀏覽器對* 該跨域請求進(jìn)行預(yù)檢的時間間隔。單位為秒。文章來源:http://www.zghlxwxcb.cn/news/detail-730660.html
以下是一個常見的跨域響應(yīng)頭的配置示例:文章來源地址http://www.zghlxwxcb.cn/news/detail-730660.html
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Content-Type, Authorization
Access-Control-Max-Age: 3600
到了這里,關(guān)于跨域介紹及Java中常見的跨域解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!