一、跨域的概念
跨域(Cross-Origin)指的是在Web应用程序中,一个域的文档或脚本试图请求另一个域的资源,而这两个域的协议、主机或端口不同。由于浏览器的同源策略(Same-Origin Policy)限制,这种跨域的请求通常会被拦截。
定义总是晦涩难懂,举个实际开发的例子会更容易理解。比如说:
现在用户打开浏览器,向前端服务发送请求,访问地址是http://localhost:5173
,得到前端返回的Web页面。现在用户进行了注册/登录等点击操作,由于前端页面是运行在浏览器上,浏览器就发送post请求给服务器,服务器访问地址是http://localhost:8081
,两者协议和主机相同但端口不同,已经跨域。浏览器会先发送preflight request
(预测试请求)到服务器,查看服务器返回的response
是否携带报文头Access-Control-Allow-Origin
,若缺少该header
则浏览器判定服务器不允许不同域的应用进行资源请求,因此浏览器发出Error:已被CORS策略阻止。
二、同源策略
同源策略是浏览器的一个重要安全特性,它限制了一个网页或脚本如何与不同源的服务器进行交互。具体来说,同源策略要求一个网页的JavaScript脚本只能访问与其来源相同的资源,而不能直接访问其他来源的资源。这是为了防止恶意网站盗取用户的数据或执行恶意操作。
ccess to XMLHttpRequest at 'http://localhost:8081/pod/create' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
三、跨域请求被拦截的原因
- 保护用户隐私:如果浏览器允许在当前页面进行跨域请求,攻击者就可以通过其他域名下的网站获取用户的敏感信息,如用户名、密码等。
- 防止跨站脚本攻击:跨站脚本攻击(XSS)是一种常见的网络攻击方式,攻击者可以在其他网站上注入恶意代码,窃取用户信息或进行其他恶意行为。如果浏览器允许跨域请求,这种攻击将变得更加容易。
- 防止URL篡改:攻击者可能会篡改URL,导致用户访问到恶意网站或进行其他非法操作。跨域请求的限制可以减少这种风险。
四、如何允许跨域
1、后端加上@CrossOrigin注解
在Controller类上面加上@CrossOrigin
,表明后端允许所有接口地址接收跨越请求。如果你在具体方法上面加上该注解就表明后端只允许该接口接收跨越请求。
2、前端加上代理服务器
前端使用代理服务器转发浏览器请求给后端,'/api'
表示代理的接口,target表示目标服务器的IP地址和端口号,pathRewrite
中写访问地址重写的策略,使用replace()函数就是为了去掉初始请求中的/api
。
这样浏览器发送post请求先到代理服务器(就是前端),请求地址为http://localhost:5173/api/pod/create,代理服务器接收到该请求,根据代理策略,会将请求源修改为http://localhost:8081
,并把/api
替换为空,得到我们想访问的目的地址http://localhost:8081/pod/create
,然后转发该post请求给目标服务器。
module.exports = {
devServer: {
proxy: {
// 获取路径中包含/api的请求
'/api': {
// 后台服务器所在源
target: 'http://localhost:8081',
// 允许修改源
changeOrigin: true,
// api替换为''
pathRewrite: {
'/api': ''
}
}
}
}
}
五、依然不能跨域的排查
通常在后端加上@CrossOrigin注解就能解决90%的问题。如果还不行,可以从下面几个方面考虑:
- 跨域问题(CORS):
检查后端服务器是否配置了正确的CORS策略,允许来自您前端域的请求。可以在浏览器的开发者工具中的“网络”选项卡里查看请求的详细信息,特别是响应头中的Access-Control-Allow-Origin
字段。
后端不要主动加上Access-Control-Allow-Origin响应头,我因为加上@CrossOrigin注解后又加上了响应头,导致下面重复包含的报错,但是状态码是200。
- 网络问题:
检查网络连接是否正常。如果前端和后端部署在不同的网络环境(如开发环境和生产环境),请确保它们之间的网络是互通的。
- 服务器问题:
检查后端服务器是否正在运行并且监听在正确的端口上。检查服务器日志以查看是否有关于请求的错误信息。application.properties
检查端口,Controller
检查接口地址。
- 请求配置问题:
检查Axios请求配置是否正确,包括URL、方法(POST)、请求头和数据体
。确保没有在请求中发送了服务器无法处理的非法数据。记住请求的地址一定要仔细检查,最后不要加上斜杠!!!
-
- 错误写法:
-
- 正确写法
// 使用 axios 发送 POST 请求到后端 API
const response = await axios.post('http://localhost:8081/pod/create', podData);
- 浏览器控制台和安全软件:
查看浏览器控制台中是否有其他相关的错误信息或警告。检查是否有安全软件(如防火墙或浏览器插件)阻止了请求。
- Axios库的问题:
确保使用的Axios库是最新的,或者至少是一个没有已知网络问题的版本。
- 调试和日志记录:
在发送请求之前和之后添加日志记录,以帮助确定问题发生的确切位置。
使用浏览器的开发者工具来跟踪网络请求和响应。