为什么127.0.0.1和localhost之间算跨域?

原文:https://mp.weixin.qq.com/s/4zJBMNEntwjqAfN6A6diUA

什么是同源策略、跨域

跨域问题是指在浏览器中,当一个网页向不同域名、不同端口或不同协议的资源发起请求时,会受到限制。这是由浏览器的**同源策略(Same-Origin Policy)**所导致的安全限制。

同源策略规定,浏览器允许页面中加载的脚本只与其来源相同的资源进行交互,包括协议(http或https)、主机/域名(domain)、端口(port)

同源策略的主要目的是保护用户的隐私和安全,防止恶意网站通过脚本获取用户的敏感信息或执行恶意操作。如果没有同源策略的限制,恶意网站就可以通过脚本来读取用户在其他网站上的数据,或者在用户不知情的情况下执行一些危险的操作。

如果两个页面的协议、主机或端口有任何一个不同,就被认为是跨域请求,浏览器就会阻止页面获取到其响应

跨域请求示例

通常情况下,在跨域请求当中,涉及到两个请求过程,第一次是预检请求(OPTIONS请求),用于验证服务器是否允许跨域请求,服务器会在响应中携带头部信息给浏览器,浏览器再发送第二次实际的跨域请求,然后服务器接收请求后再进行处理,并在响应中包含必要的头部信息。

图片

注意:在一些特殊情况下,如果服务器已经配置允许来自所有源的请求(使用通配符 *),或者服务器与客户端位于同一源(同源请求),那么只会发送一次实际请求而不需要预检请求。但这通常不是最佳的安全做法,因为它可能会导致安全漏洞。

为什么127.0.0.1和localhost之间算跨域?

经过上面的了解,我们再回到刚开始的问题,为什么127.0.0.1和localhost之间算跨域?

实际就是浏览器的同源策略导致的。虽然它俩指向的都是同一个 IP 地址,即本地主机。

但从浏览器的角度来看,它们仍然被视为不同的域。这是因为浏览器在处理跨域请求时,会将协议+域名+端口号 作为标识符。很显然比如http://localhost:3000/http://127.0.0.1:3000/,它们的主机/域名(domain)是不一样的,因此会出现跨域。

如何解决跨域问题

法1:修改前端的请求URL

首先针对于上述出现的127.0.0.1localhost之间的跨域,最简单的办法就是将前端设置的请求url修改为localhost即可。如下是修改之后进行测试的结果:

图片

法2:spring提供的简化跨域配置的机制

Spring框架提供了一些简化跨域配置的方法,主要是通过Spring Web模块(通常与Spring Boot结合使用)来实现的。

1、使用@CrossOrigin注解:在Controller层,你可以为特定的处理方法或整个控制器类添加@CrossOrigin注解,以声明允许的跨域请求。

图片

2、使用全局配置:如果要在整个应用程序中配置跨域规则,可以使用全局配置。通过CorsRegistry来配置全局跨域规则。

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("**") // 设置路径匹配模式
                .allowedOrigins("http://localhost:8080") // 允许的来源
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
                .allowedHeaders("Origin", "Content-Type", "Accept") // 允许的HTTP头
                .allowCredentials(true) // 支持用户凭证
                .maxAge(3600); // 缓存时长
    }
}

在上面的示例中,我们创建了一个名为WebConfig的配置类,使用addCorsMappings方法定义了CORS规则,允许来自https://localhost:8080的跨域请求,并指定了允许的HTTP方法、请求头和缓存时间。

通过Nginx反向代理

在分布式项目当中,我们也可以通过Nginx反向代理来解决跨域问题:

在配置文件当中进行配置:

# 设置 HTTP 服务器
server {
    listen 80;
    server_name localhost;

    # 配置反向代理,将 localhost:8080 的请求转发到 localhost:8081
    location / {
        proxy_pass http://localhost:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # 添加跨域头信息
        add_header 'Access-Control-Allow-Origin' 'http://localhost:8080';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        
        # 处理 OPTIONS 请求的头信息
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
    }
}

目前,跨域问题的解决方案有多种选择,但其中CORS(跨域资源共享)和服务器端代理是最常用的,它们具备良好的灵活性和安全性,适用于许多不同的应用场景。不过尽管有多种可行的方法,但我们仍然需要根据具体的情况来选择最合适的解决方案,以确保跨域问题能够得到有效解决。

总结

  • 跨域的必要性和重要性:跨域的必要性和重要性在于保护用户数据和隐私、维护互联网生态系统的安全和稳定。
  • 合适的跨域解决方案:根据具体的需求和环境,选择合适的解决方案来确保跨域请求的安全性、兼容性、功能性、性能和维护性。
  • 分布式系统当中的跨域:跨域在分布式系统当中尤为常见,分布式系统通常由多个独立部署的服务或模块组成,这些服务可能运行在不同的域名、主机端口上。当一个服务需要与另一个服务或模块进行通信时,就会涉及到跨域请求。这里大家可以入手我的分布式课程,里面内容丰富,能够帮助大家深入分析和解读代码当中的内在逻辑
  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值