本文主要介紹的解決方式:
- Vue 項(xiàng)目中配置代理
- 后端注解 @CrossOrigin
- 繼承 WebMvcConfigurer 的全局配置類
跨域其實(shí)并不是一種問題,而是瀏覽器的安全機(jī)制。在 Web 開發(fā)中,由于瀏覽器的同源策略限制,導(dǎo)致不同源(域、協(xié)議、端口)之間的網(wǎng)頁訪問受到限制或出現(xiàn)安全問題。
協(xié)議://域名:端口(如 http://localhost:8080): 同源策略表示協(xié)議、域名和端口必須一致。比如在前后端分離項(xiàng)目中,后端項(xiàng)目運(yùn)行在本機(jī)的 8080 端口,前端運(yùn)行在 80 端口,這樣前端訪問后端就會(huì)因?yàn)椴煌矗ǘ丝诓煌?dǎo)致跨域限制。
解決跨域問題可以通過下面幾種方式:
- 跨域資源共享 ( CORS ):服務(wù)端設(shè)置響應(yīng)頭,允許特定源訪問資源;
- JSONP ( JSON with Padding ):利用 Script 標(biāo)簽可以跨域的特性,在前端頁面通過動(dòng)態(tài)創(chuàng)建 Script 標(biāo)簽來獲取跨域數(shù)據(jù);
- 代理:后端通過代理將請(qǐng)求轉(zhuǎn)發(fā),避免前端直接跨域請(qǐng)求;
- 服務(wù)器設(shè)置跨域規(guī)則:配置服務(wù)器,使其允許跨域請(qǐng)求訪問資源。
方式一:前端配置
-
Vue 項(xiàng)目,在 vite.config.js 文件中可添加如下代理配置,在該文件最后另起一行進(jìn)行添加即可。
module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8989', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }以上配置是將帶有
/api前綴的請(qǐng)求進(jìn)行代理,將其代理到 'http://localhost:8989',并將/api去掉 如果項(xiàng)目中的 Axios 配置文件 (我的項(xiàng)目中該配置的文件名是 axios.js)有配置 baseURL 完整路徑的,則需要將
協(xié)議://域名:端口部分去掉,只保留一個(gè)/api/。這樣做的目的是:所有的 Ajax 請(qǐng)求都會(huì)加一個(gè)/api/前綴,然后所有帶有/api前綴的又將被代理到http://localhost:8989,從而避免瀏覽器的跨域限制。
import axios from 'axios';
// 創(chuàng)建一個(gè) Axios 實(shí)例,可以給所有的請(qǐng)求都加上一個(gè) /api 前綴
const http = axios.create({
baseURL: '/api/'
});
export default http;
方式二:后端注解 @CrossOrigin
前面介紹的是前端配置咯,其實(shí)在后端也可以解決跨域問題。
- 在控制類上加注解 @CrossOrigin,然后通過 origins 參數(shù)指定允許跨域訪問的域地址。
@RestController
@RequestMapping("/api/test")
//@CrossOrigin
@CrossOrigin(origins = {"http://localhost:5173", "https://xxxx.com"})
public class TestController {
// @CrossOrigin(origins = "http://xxx.icu")
@GetMapping()
public String test() {
return "test success!!!";
}
}
origins: 允許可訪問的域列表;
maxAge: 準(zhǔn)備響應(yīng)前的緩存持續(xù)的最大時(shí)間(單位秒);
@CrossOrigin 后面不加任何參數(shù),表示允許所有源訪問。其后可以通過 origins 參數(shù)指定一個(gè)或多個(gè)域,表示允許這些指定的域進(jìn)行訪問。該注解也可以加在方法上,含義一樣,表示允許跨域訪問該方法。
方式三:配置全局跨域支持
創(chuàng)建一個(gè)繼承自 WebMvcConfigurer 的配置類,重寫其中的 addCorsMappings 方法來配置允許跨域的規(guī)則。(注意類上要加 @Configuration 注解表面這是一個(gè)配置類,并將其交由 Spring 容器管理)
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowCredentials(true)
.allowedHeaders("token")
.maxAge(3600);
}
}
addMapping("/**"): 指定允許跨域訪問的路徑,通常是所有路徑;
allowedOriginPatterns(“*"): 表示允許所有的來源;
allowedOrigins("http://xxx.com"): 表示允許指定的來源,區(qū)別在于 allowedOriginPatterns() 可以進(jìn)行模式匹配,而這個(gè)需要指定明確地地址;
allowedMethods("*"): 表示允許所有的 HTTP 方法進(jìn)行跨域請(qǐng)求;
allowedCredentials(true): 允許跨域請(qǐng)求攜帶身份憑證 (如 cookies、HTTP 認(rèn)證信息等);
allowedHeaders("token"): 指定了允許跨域請(qǐng)求攜帶的請(qǐng)求頭信息,這里表示只允許攜帶名為 "token" 的請(qǐng)求頭;
maxAge(3600): 指定預(yù)檢請(qǐng)求有效期,即在多久內(nèi)不需要再發(fā)送預(yù)檢請(qǐng)求,這里是 3600 秒(1 小時(shí))。