跨域及解决方案
一、概述
1.1 同源策略
同源策略/SOP(Same origin policy)是一种约定,由 Netscape 公司 1995 年引入浏览器,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。如果缺少了同源策略,浏览器很容易受到 XSS、 CSFR 等攻击。
同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。
源就是协议、域名和端口号。
协议:http,https
域名:区域的名字,每个域名都对应一个IP地址, 举个例子:域名:www.baidu.com,http://180.101.49.12/
180.101.49.12则为IP地址
1.1.1 技术
浏览器
1.1.2 概念
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
二、产生跨域场景
2.1 跨域产生
当资源访问的两端在 协议、域名、端口号 三者中任一项不同,则就会产生跨域问题。
2.1.1 localhost与127.0.0.1区别
locahost | 127.0.0.1 | 本机IP | |
---|---|---|---|
实质 | 域名:通过host文件绑定到了127.0.0.1地址上 | IP地址 | 暴露在外网上的IP地址 |
对应环境 | 本机服务器 | Windows系统中表示本机IP地址 | 本机IP地址 |
网络要求 | 不需要联网 | 不需要联网 | 需要联网 |
数据传输限制 | 不经过网卡,不受防火墙和网卡限制 | 经过网卡,受防火墙和网卡限制 | 经过网卡,受防火墙和网上限制 |
访问限制 | 本机访问 | 本机访问 | 本机与外网访问 |
2.2 跨域问题影响
- 跨域仅影响ajax|axios|XmlHttpRequest发起的各类请求。
- 常用的Http标签如:img、a、script、form等通过src属性发起的请求不受跨域影响。
三、跨域解决方案
3.1 跨域请求的配置核心项
跨域主要涉及4个响应头:
Access-Control-Allow-Origin
: 用于设置允许跨域请求源地址 (预检请求和正式请求在跨域时候都会验证)Access-Control-Allow-Headers
: 跨域允许携带的特殊头信息字段 (只在预检请求验证)Access-Control-Allow-Methods
: 跨域允许的请求方法或者说HTTP动词 (只在预检请求验证)Access-Control-Allow-Credentials
: 是否允许跨域使用cookies,如果要跨域使用cookies,可以添加上此请求响应头,值设为true(设置或者不设置,都不会影响请求发送,只会影响在跨域时候是否要携带cookies,但是如果设置,预检请求和正式请求都需要设置)。
3.2 前端Vue代理跨域
module.exports = {
lintOnSave: false,
devServer: {
proxy: {
'/api': {
ws: true,
target: 'http://127.0.0.1:8210',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}
}
}
}
3.3 nginx代理跨域
server {
listen 22222;
server_name localhost;
location / {
add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Credentials 'true';
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://localhost:59200;
}
}
3.4 SpringBoot配置类跨域
Spring团队推荐跨域方式
@Configuration
public class MyCrosConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer()
{
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8092", "http://localhost:8093", "http://localhost:8080")
.allowCredentials(false)
.allowedHeaders("*")
.allowedMethods("*");
}
};
}
}
3.5 SpringWeb注解跨域
@CrossOrigin()