清晰易懂的跨域请求知识——拿捏

1. 什么是跨域请求?

  • 简单来说:当你的 前端网页(例如 http://frontend.com)通过 JavaScript 调用 后端接口(例如 http://backend.com/api)时,如果两者的 域名、端口、协议 中任意一项不同,浏览器会认为这是「跨域请求」,默认会阻止请求(出于安全考虑)。
  • 核心限制:这个限制是由浏览器的 同源策略(Same-Origin Policy) 触发的,目的是防止恶意网站窃取用户数据。

2. 什么是「同源」?

  • 同源的定义:两个 URL 的以下三项必须完全相同
    1. 协议(如 http vs https
    2. 域名(如 frontend.com vs api.frontend.com
    3. 端口(如 80 vs 8080
  • 举例
    • 前端:http://localhost:3000
    • 后端:http://localhost:8080
    • 不同源!因为端口不同(3000 vs 8080)。

3. 为什么前后端分离会触发跨域问题?

在前后端分离架构中:

  • 前端:独立部署在一个服务器(如 http://frontend.com:3000)。
  • 后端:独立部署在另一个服务器(如 http://backend.com:8080)。
  • 问题:前端通过 JavaScript(如 fetchaxios)调用后端接口时,浏览器会拦截请求,并报错:
    Access to fetch at 'http://backend.com:8080/api/data' from origin 'http://frontend.com:3000' 
    has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

4. 如何解决跨域问题?

方法 1:后端配置 CORS(推荐)
  • CORS(跨域资源共享):后端在响应头中添加允许跨域的规则。
  • 示例(以 Node.js 为例):
    // 后端代码
    const express = require('express');
    const app = express();
    
    // 添加 CORS 头
    app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', 'http://frontend.com:3000'); // 允许前端的域名
      res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');    // 允许的请求方法
      res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的请求头
      next();
    });
    
    app.get('/api/data', (req, res) => {
      res.json({ message: 'Hello from backend!' });
    });
    
    app.listen(8080);
    
方法 2:前端代理(开发环境常用)
  • 原理:让前端服务器(如 webpack-dev-server)代理请求到后端,隐藏跨域。
  • 示例(React 项目配置):
    1. package.json 中添加代理:
      {
        "proxy": "http://backend.com:8080"
      }
      
    2. 前端代码直接请求 /api/data(而不是写完整后端地址):
      fetch('/api/data') // 实际请求会转发到 http://backend.com:8080/api/data
        .then(response => response.json());
      
方法 3:JSONP(历史方案,已淘汰)
  • 原理:利用 <script> 标签不受跨域限制的特性(仅支持 GET 请求)。
  • 示例
    // 前端
    function handleResponse(data) {
      console.log(data);
    }
    const script = document.createElement('script');
    script.src = 'http://backend.com:8080/api/data?callback=handleResponse';
    document.body.appendChild(script);
    
    // 后端返回
    handleResponse({ message: 'Hello from JSONP!' });
    

5. 实际场景示例

场景 1:前端调用后端 API
  • 前端代码(React):
    // 前端运行在 http://localhost:3000
    fetch('http://localhost:8080/api/data')
      .then(response => response.json())
      .then(data => console.log(data));
    
  • 后端代码(Spring Boot):
    @RestController
    @CrossOrigin(origins = "http://localhost:3000") // 允许前端跨域
    public class DataController {
      @GetMapping("/api/data")
      public String getData() {
        return "Hello from backend!";
      }
    }
    
场景 2:浏览器报错示例

如果后端未配置 CORS,浏览器会拦截响应并提示:

Access to fetch at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.

6. 总结

  • 跨域的本质:浏览器为了安全限制不同源的请求。
  • 解决方法
    • 后端配置 CORS(生产环境推荐)。
    • 前端代理(开发环境常用)。
    • JSONP(已淘汰,仅作了解)。
  • 关键点:跨域是浏览器的行为,后端接口本身可以被调用,但需要明确告知浏览器允许跨域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tee xm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值