当前位置: 首页 > article >正文

跨域问题的产生和解决

1. 为什么会产生跨域

        前后端分离模式下,客户端请求前端服务器获取视图资源,然后客户端自行向后端服务器获取数据资源,前端服务器的协议、IP和端口和后端服务器很可能是不一样的、这样就产生了跨域。

        这主要是因为浏览器的同源策略导致的,同源策略要求网页资源(如 JavaScript、CSS、图片等)只能与来源相同的资源进行交互,即只能与相同域名、相同协议和相同端口的资源进行通信。例如,一个网页加载自 https://www.example.com 域名下的资源,就只能与同一域名下的其他资源进行交互,无法直接访问其他域名的资源。

        同源策略主要限制了以下几种行为:

  • DOM 访问限制:不同源的页面无法通过 JavaScript 等方式直接访问对方的 DOM 元素,即无法获取或修改对方页面的内容。
  • Cookie、LocalStorage 和 IndexDB 限制:不同源的页面无法读取对方设置的 Cookie、LocalStorage 和 IndexDB 存储。
  • AJAX 请求限制:XMLHttpRequest、Fetch 等网络请求在跨域时受到限制,通常无法发送跨域请求。

        请求如果跨域的话不是请求无法发出,请求可正常发出,而且服务端能收到请求并正常返回结果,但是被浏览器拦截了。同源策略的存在有效地防止了跨站脚本攻击(XSS)和跨站请求伪造(CSRF)等安全威胁。如果需要在不同源之间进行数据交互,可以通过服务器端的代理或使用 CORS(跨源资源共享)等技术来实现。

2. 浏览器拦截机制


‌2.1 简单请求‌

‌定义‌:请求方法是GET、HEAD、POST;
‌条件‌:HTTP头信息不超出Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width;
‌Content-Type‌:仅限于application/x-www-form-urlencoded、multipart/form-data、text/plain;

拦截机制‌:简单跨域请求浏览器会自动带上Origin头部,用于标识请求的源(origin)。如果服务器响应头Access-Control-Allow-Origin,值包含请求的源,浏览器会允许跨域请求。否则,浏览器会拦截该请求的返回值。

2.2. 复杂请求‌

‌定义‌:请求方法是PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH;
‌条件‌:HTTP头信息超出简单请求的范围;
‌Content-Type‌:不属于application/x-www-form-urlencoded、multipart/form-data、text/plain;

拦截机制‌:复杂跨域请求浏览器会先发送一个OPTIONS预检请求(preflight request)到服务器,询问是否允许跨域请求。如果服务器允许,预检通过后才会发送真正请求并在服务端被执行。


3. 后端CORS解决方案

        CORS (Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

        CORS是通过收到浏览器的预检请求后,设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后,就会对正式请求数据的响应进行放行。
        简单配置方式:
@RestController
@CrossOrigin(origins = "http://example.com")
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "hello world";
    }
}

        配置方式:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 配置跨域支持
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")		//允许的路径,即我们那些接口可以跨域
                .allowedOrigins("http://example.com")		//允许的源
                .allowCredentials(true) 	//是否允许发送凭证
                .allowedMethods("GET","POST","PUT","DELETE")  //指定允许的 HTTP 方法
                .maxAge(3600 * 24);		//预检请求有效期
    }

4. 前端Nginx解决方案

        通过 Nginx 反向代理可以有效地解决跨域问题。

        假设有两个域名为 example.com 和 api.example.com,我们希望在 example.com 上通过 AJAX 请求获取 api.example.com 上的数据,但由于跨域限制,请求被浏览器拦截了。我们可以通过 Nginx 配置反向代理来解决这个问题。

        首先,确保 Nginx 已经安装并运行。编辑 Nginx 的配置文件,通常位于 /etc/nginx/nginx.conf 或 /etc/nginx/sites-available/default。

server {
    listen 80;
    server_name example.com;

    location /api {
        # 定义代理目标
        proxy_pass http://api.example.com;
        # 允许跨域请求
        add_header Access-Control-Allow-Origin *;
        # 允许带身份验证信息的跨域请求
        add_header Access-Control-Allow-Credentials true;
        # 允许的请求方法
        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';
        # 预检请求的有效期
        add_header Access-Control-Max-Age 3600;
        # 处理 OPTIONS 请求
        if ($request_method = 'OPTIONS') {
            add_header Content-Type 'text/plain; charset=utf-8';
            add_header Content-Length 0;
            return 204;
        }
    }
}

5. 两种解决方案对比

方法优点缺点适用场景
Nginx性能高、集中配置、灵活性强配置麻烦、依赖Nginx同域访问、微服务集中代理
CORS轻量级、细粒度控制预检请求多、配置分散不同域访问,需精细跨域控制

http://www.kler.cn/a/395324.html

相关文章:

  • 计算机毕业设计Python+大模型中医养生问答系统 知识图谱 医疗大数据 中医可视化 机器学习 深度学习 人工智能 大数据毕业设计
  • 【视觉SLAM】1-概述
  • u盘加密软件有哪些?2025年必备的u盘加密神器分享(共6款!提前布局!)
  • C++算法练习-day40——617.合并二叉树
  • JavaScript 观察者设计模式
  • react 中 useContext Hook 作用
  • 【MatLab手记】 --从0到了解超超超详过程!!!
  • JWT深度解析:Java Web中的安全传输与身份验证
  • 雷光联动自动化标校方法
  • Python自动化小技巧24——实现自动化输出模板表格报告
  • react 受控组件和非受控组件
  • 使用git命令实现对gitee仓库的下载、更新、上传、上传更新操作。
  • FluentUI使用
  • kafka 生产经验——数据积压(消费者如何提高吞吐量)
  • 图像处理技术椒盐噪声
  • [C++刷题] 基础小知识点(5) 数字反转\求数字位数
  • Vue2:脚手架 vue-cli
  • UDP/TCP 简述
  • Elasticsearch集群和Kibana部署流程
  • 【OceanBase 诊断调优】—— OceanBase 数据库统计信息被禁用,状态为 broken 的原因和解决方法
  • 【论文阅读】Virtual Compiler Is All You Need For Assembly Code Search
  • 数位DP学习
  • 人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例
  • 【数字图像处理+MATLAB】基于 Sobel 算子计算图像梯度并进行边缘增强:使用 imgradientxy 函数
  • 《Java核心技术 卷I》Swing处理2D图形
  • 探索 Python HTTP 的瑞士军刀:Requests 库