• 跨域问题总结


    概要

    在不成熟的前后端开发过程中,经常遇到跨域问题;
    前后端分离的模式下的开发过程中,经常遇到跨域问题;

    本文章针对跨域问题提供几个有效的解决方案;

    web应用整体请求流程

    前端给后端发ajax、aioxs,中间要经过web服务器转手,然后后端接收请求、处理、响应,
    有些情况下,可能没有web服务器这一步,这是一个闭环;

    技术名词解释

    跨域(Cross-Origin)是指在Web开发中,当前前端页面所在的域(域名、协议、端口)与请求的目标资源的域不一致时,浏览器会阻止页面发起跨域请求。这是出于安全考虑,以防止恶意网站获取用户的敏感信息或进行其他安全攻击。

    跨域问题主要涉及到浏览器的同源策略(Same-Origin Policy)。同源策略要求网页只能从同一域的源加载资源,不同源的资源请求将会受到限制。

    具体而言,同源策略包括以下几个方面:

    协议相同: 两个页面的协议必须相同,比如都是http或https。
    域名相同: 两个页面的域名必须相同,包括主域名和子域名。
    端口相同: 两个页面的端口号必须相同。

    跨域问题产生的原理

    就是因为浏览器的同源策略,导致前端通过浏览器发给后端的请求,被浏览器阻止了。

    解决方案

    前端代码角度

    如果你的前端是框架开发的,前端代码里可以用代理的方式实现。比如:

      server: {
       proxy: {
         '/common': {
           target: envs.VITE_API_BASE_URL,
           changeOrigin: true,
           secure: false,
         },
         '/iot': {
           target: envs.VITE_API_BASE_URL,
           changeOrigin: true,
           secure: false,
         },
         '/farm': {
           target: envs.VITE_API_BASE_URL,
           changeOrigin: true,
           secure: false,
         },
         '/admin': {
           target: envs.VITE_API_BASE_URL,
           changeOrigin: true,
           secure: false,
         }
       },
     },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    前端服务器角度

    可以在前端web服务器配置文件内写反代,原理就是前端请求当前域名/api,这样浏览器就不会报错,前端web服务器接收到api的请求时去转发请求到后端服务器,

    server {
        listen 80;
        server_name your_domain.com;  # 替换为你的域名
    
        location / {
            root /path/to/your/frontend/app;  # 替换为你的前端应用的路径
            index index.html;
            try_files $uri $uri/ /index.html;
        }
    
        location /api/ {
            proxy_pass http://localhost:5000;  # 替换为你的API服务器地址和端口
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    
        # 可以添加其他配置,如SSL证书等,根据实际需求
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    后端代码角度

    // 允许任何来源访问
    header("Access-Control-Allow-Origin: *");
    
    // 允许的请求方法
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    
    // 允许的请求头字段
    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
    
    // 响应类型
    header("Content-Type: application/json; charset=utf-8");
    
    // 如果是预检请求(OPTIONS),直接返回空响应体,结束执行
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        header("HTTP/1.1 200 OK");
        exit();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    有些框架比如laravel,还支持中间价的优雅语法实现,和这个代码大同小异,可以自行百度

    后端服务器角度

    server {
        listen 80;
        server_name your_domain.com;  # 替换为你的域名
    
        location / {
            # 允许任何来源访问
            add_header 'Access-Control-Allow-Origin' '*';
            # 允许的请求方法
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            # 允许的请求头字段
            add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
            # 响应类型
            add_header 'Content-Type' 'application/json; charset=utf-8';
    
            # 可以添加其他配置,如代理到后端应用等,根据实际需求
        }
    
        # 可以添加其他配置,如SSL证书等,根据实际需求
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    小结

    一个请求的发起到后端接收到后端响应,这是一个闭环的流程,在这个流程上的每一步都可以实现跨域问题的解决

  • 相关阅读:
    新版selenium4.0 + Python使用详解
    如何使用Java反射?(反射篇 二)
    运维工作的“本手、妙手、俗手”
    为什么独立站卖家都开始做社交媒体营销?原来客户转化率能提高这么多!
    C++&QT---QT-day2
    VPN技术简介
    linux lsmod(查看驱动模块)和 ls /dev(驱动设备)
    LeetCode 230.二叉搜索树中第K小的元素
    在vue-cli脚手架项目中使用bootstrap框架和jquery
    java-导出Export
  • 原文地址:https://blog.csdn.net/weixin_45316408/article/details/136553228