文章目录
一、前端的配置
在vue项目中进行配置, 从而使 /api
开头的请求都会被代理到制定的域名, 从而避免跨域问题
1.1 在 vue.config.js
文件中添加如下配置
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://your-api-server.com', // 目标接口的域名
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/api': '' // 重写路径,去掉 `/api` 前缀
}
}
}
}
}
1.2 在 axios
的请求中, 需要使用 /api
作为前缀
axios.get('/api/some-endpoint')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
二. 在后端配置
2.1 添加全局配置
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:80") // 明确指定允许的域名
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true) // 允许凭证
.maxAge(3600);
}
}
注:
-
- 如果不需要凭证(如 Cookies 或 Authorization 头),可以将
allowCredentials
设置为false
- 如果不需要凭证(如 Cookies 或 Authorization 头),可以将
-
- 当使用
.allowedOrigins("*")
报错When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.] with root cause
, 则需要明确制定允许的域名
- 当使用
-
- 当已经重写过
WebMvcConfigurer
的其余实现类时, 再次添加CorsConfig
可能会被覆盖而导致失效
- 当已经重写过
-
- 快捷键
ctrl + H
查看结构层次, 确定WebMvcConfigurer
是否已经被重写
- 快捷键
2.2 使用 CorsFilter
当需要更细粒度的控制时, 可以使用 CorsFilter
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 允许凭证
config.addAllowedOrigin("http://localhost:80"); // 明确指定允许的域名
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
2.3 在 Controller
上单独配置
当只需要为某些 Controller 或方法配置 CORS,可以使用 @CrossOrigin
注解
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://localhost:80", allowCredentials = "true") // 明确指定允许的域名
public class MyController {
@GetMapping("/api/data")
public String getData() {
return "Hello from Java backend!";
}
}
三. 什么是跨域问题
跨域问题是在网络开发中,当一个网页或应用程序试图从一个域名(源)去访问另一个不同域名(目标)的数据或资源时,由于浏览器的同源策略限制而引发的问题。
产生原因
- 同源策略:这是浏览器的一种安全机制,它要求浏览器在执行脚本、请求数据等操作时,确保请求的源(协议、域名、端口号)与当前页面的源相同。例如,https://www.example.com与https://www.example.net,虽然主域名相似,但仍是不同域名,若从前者页面去访问后者资源就会触发跨域问题。
- 实际应用需求:在现代 Web 开发中,经常会出现需要从不同域名获取数据或资源的情况。比如,一个网站可能需要调用第三方的 API 来获取数据,或者加载来自 CDN(内容分发网络)的静态资源等,这些操作很容易导致跨域请求的发生。
常见场景
- AJAX 请求跨域:在使用 JavaScript 的 AJAX 技术向不同域名的服务器请求数据时,如果服务器没有进行相应的配置允许跨域访问,就会出现跨域问题。浏览器会阻止这种跨域的 AJAX 请求,并在控制台中显示错误信息。
- 跨域加载脚本、样式和图片:虽然浏览器通常允许跨域加载一些静态资源,如脚本、样式表和图片,但在某些情况下,如果服务器配置不当或者需要进行更精细的权限控制,也可能会出现跨域问题。比如,当尝试通过
<script>
标签加载一个来自不同域名的 JavaScript 文件时,如果目标服务器不允许跨域访问,可能会导致脚本无法加载或执行。 - iframe 跨域:当在一个页面中使用
<iframe>
标签嵌入另一个不同域名的页面时,两个页面之间的交互可能会受到跨域限制。例如,父页面想要访问 iframe 子页面中的内容或执行子页面中的脚本,就可能会因为跨域问题而失败。
解决方法
- CORS(跨域资源共享):这是一种在服务器端进行配置的机制,通过在服务器响应头中添加特定的字段,来告诉浏览器哪些域名可以访问该服务器的资源,以及允许进行哪些类型的跨域操作。例如,服务器可以设置Access-Control-Allow-Origin头来指定允许访问的源。
- JSONP(JSON with Padding):利用
<script>
标签没有跨域限制的特点,通过动态创建<script>
标签来请求数据,并在服务器端将数据以特定的格式返回,在客户端通过回调函数来处理返回的数据。不过,JSONP 只支持 GET 请求,有一定的局限性。 - 代理服务器:在客户端和目标服务器之间搭建一个代理服务器,客户端先将请求发送到代理服务器,代理服务器再将请求转发到目标服务器,并将目标服务器的响应返回给客户端。这样,对于客户端来说,所有的请求都是在同一个域名下进行的,从而避免了跨域问题。
四. 为什么有浏览器的同源策略限制
浏览器的同源策略限制是一种重要的安全机制,主要是为了防止恶意网站窃取用户信息、执行恶意操作等
保护用户隐私和数据安全
- 防止跨站脚本攻击(XSS):恶意网站可能会利用同源策略的缺失,在用户访问的合法页面中注入恶意脚本。如果没有同源策略,这些脚本就能够获取用户在该页面上输入的敏感信息,如用户名、密码、信用卡号等,然后将这些信息发送给攻击者。例如,用户在银行网站登录后,如果另一个恶意网站可以随意访问银行网站的内容,就可能通过脚本获取用户的银行账户信息,导致用户资金被盗。
- 保护用户浏览历史等信息:同源策略可以防止一个网站随意读取用户在其他网站的浏览历史、Cookie 等信息。这些信息可能包含用户的个人偏好、登录状态等敏感内容,如果被恶意网站获取,可能会被用于精准的广告投放、用户画像分析,甚至是进一步的攻击。
防止数据篡改和恶意操作
- 防止跨站请求伪造(CSRF):攻击者可能会构造一个恶意链接或页面,诱导用户点击。如果没有同源策略限制,当用户登录了某个网站(如购物网站、社交网站等)并处于登录状态时,点击了恶意链接,恶意网站可能会利用用户的登录状态,向目标网站发送请求,执行一些用户不知情的操作,如修改用户密码、发送恶意邮件、进行购物下单等。同源策略能够限制跨域请求,使得目标网站可以验证请求是否来自合法的源,从而防止此类攻击。
- 保护网站数据完整性:对于一些需要进行数据交互和操作的网站,如在线文档编辑、企业管理系统等,同源策略可以确保只有来自同一源的请求才能对数据进行修改和操作。否则,恶意网站可能会随意篡改这些数据,导致数据丢失、错误或混乱,影响网站的正常运行和用户的正常使用。
维护浏览器环境的稳定性和安全性
- 防止恶意脚本干扰:不同网站的脚本可能会有不同的功能和行为,如果没有同源策略,这些脚本可能会在用户不知情的情况下相互干扰、冲突,甚至破坏浏览器的正常运行。例如,一个网站的脚本可能会修改浏览器的全局变量或对象,影响其他网站脚本的正常执行,导致页面出现错误或异常。
- 限制代码执行权限:同源策略可以根据不同的源为脚本分配不同的权限和执行环境,使得脚本只能在其所属的源范围内进行操作,避免恶意脚本在浏览器中获得过高的权限,从而防止脚本对浏览器本身以及用户的设备进行恶意操作,如删除文件、获取系统信息等。