章工运维 章工运维
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)

章工运维

业精于勤,荒于嬉
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)
  • linux

  • windows

  • 中间件

  • 网络

  • 安全

  • 存储

  • 防火墙

  • 数据库

  • 系统

  • docker

  • other

    • debian中科大替换教程
    • Alpine安装php各种扩展
    • 使用http-server启动本地服务
    • windows文件同步备份
    • axure将项目同步到svn和axhub
    • Makefile入门
    • Rsyslog开源日志服务器
    • 在windows64位系统安装mysql
    • 博客vue报错版本依赖问题解决
    • VMware搭建群晖
    • 一个开源的照片管理程序——photoprism
    • 搭建属于自己的云笔记——leanote
    • 浏览器跨域问题
      • 从0到1搭建支付和发卡系统
      • 运维常见故障及排查方法
      • 高德MCP智能体搞定旅游计划
      • 不花一分钱从0到1建站教程
    • 监控

    • 运维
    • other
    章工运维
    2024-09-11
    目录

    浏览器跨域问题

    # 浏览器的跨域和nginx proxy跨域的区别

    浏览器的跨域与Nginx 代理的跨域都是解决同源策略(Same-Origin Policy)下的跨域问题,但它们的作用方式和解决原理有所不同。

    # 1. 浏览器的跨域

    浏览器的同源策略会限制一个网站从另一个域名、协议或端口获取资源。这种限制是为了保护用户的隐私和数据安全,防止恶意网站访问敏感资源。为了在浏览器中允许跨域访问,通常需要后端服务器通过设置CORS(跨源资源共享)头来显式允许跨域请求。

    # 示例:

    假设前端页面运行在 https://example.com,而它需要从 API 服务 https://api.example.com 获取数据。

    // 前端 JavaScript 发起跨域请求
    fetch('https://api.example.com/data', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      }
    })
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error(error));
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    为了使这类请求成功,API 服务器必须返回包含以下 CORS 头的响应:

    Access-Control-Allow-Origin: https://example.com
    Access-Control-Allow-Methods: GET, POST
    
    1
    2

    特点:浏览器层面控制的跨域请求依赖于服务端的 CORS 头配置,如果服务端未正确配置,浏览器会阻止跨域请求。

    # 2. Nginx 代理的跨域

    Nginx 的代理方式可以通过将请求直接代理到目标服务器,实现跨域资源的获取。通过Nginx,前端页面和后端API看起来像是同一个域名(由Nginx代理处理),从而绕过了浏览器的同源策略限制。

    # 示例:

    前端页面运行在 https://example.com,而需要从 https://api.example.com 获取数据。通过Nginx代理,将API请求转发到实际的API服务器。

    server {
        listen 80;
        server_name example.com;
    
        location /api/ {
            proxy_pass https://api.example.com/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    现在,当用户访问 https://example.com/api/ 时,Nginx 会将请求转发给 https://api.example.com/。对于前端来说,API 请求和网页加载都来自同一个域名 https://example.com,从而避免了跨域问题。

    特点:通过Nginx代理的方式,跨域问题对浏览器透明处理,避免了浏览器层的跨域限制,不需要后端API服务器显式设置CORS头。

    # 总结:

    • 浏览器的跨域 依赖于服务端的CORS配置,允许浏览器在符合规则的情况下直接请求不同源的资源。
    • Nginx 代理跨域 则是通过反向代理,将跨域请求转化为同源请求,从而绕过了浏览器的跨域限制。

    # 什么情况下nginx才配置跨域的设置

    Nginx 通常配置跨域设置是在需要处理跨源请求时,尤其是当 Nginx 作为反向代理服务器或静态文件服务器时,需要直接响应浏览器发起的跨域请求。以下是一些具体情况下,Nginx 可能需要配置跨域设置的场景:

    # 1. 直接提供静态资源的跨域访问

    当 Nginx 被用作静态资源服务器时(例如,托管静态 HTML、CSS、JavaScript 或图片文件),而这些资源会被其他域名下的网页访问,此时可能需要启用 CORS。

    # 示例场景:

    你有一个 CDN 或静态资源服务器,位于 https://cdn.example.com,而主网站在 https://www.example.com。用户从主网站访问静态资源时,会发出跨域请求。

    在这种情况下,你可以在 Nginx 中添加 CORS 头,允许特定的域名访问资源。

    server {
        listen 80;
        server_name cdn.example.com;
    
        location / {
            # 添加 CORS 头允许跨域请求
            add_header 'Access-Control-Allow-Origin' 'https://www.example.com';
            add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Origin, Authorization, X-Requested-With, Content-Type, Accept';
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 2. 作为 API 网关时处理跨域

    当 Nginx 充当 API 网关或反向代理时,需要处理前端(例如来自 https://app.example.com 的 AJAX 请求)对不同服务器的 API 请求。如果 API 服务器没有直接返回 CORS 头,或者你希望通过 Nginx 来控制跨域逻辑,那么需要在 Nginx 中配置 CORS。

    # 示例场景:

    前端网页位于 https://app.example.com,后端 API 位于 https://api.example.com,通过 Nginx 将 API 请求代理到后端。在这种情况下,如果 API 服务器没有处理 CORS,你可以通过 Nginx 来添加跨域头。

    server {
        listen 80;
        server_name api.example.com;
    
        location / {
            proxy_pass http://backend_api_server;
            # 添加 CORS 头允许跨域请求
            add_header 'Access-Control-Allow-Origin' 'https://app.example.com';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Origin, Authorization, X-Requested-With, Content-Type, Accept';
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # 3. 前端与后端服务分离的应用

    在前后端分离的应用架构中,前端应用通常由一个域名提供服务(如 https://frontend.com),而后端 API 服务由另一个域名提供(如 https://api.frontend.com)。如果用户需要通过 AJAX、Fetch 等方式请求后端数据,则需要启用 CORS。

    此时,Nginx 可以作为反向代理服务器,配置 CORS 设置来允许跨域请求。

    server {
        listen 80;
        server_name api.frontend.com;
    
        location / {
            proxy_pass http://backend_service;
            # 允许所有域访问(或者限定特定域名)
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Origin, Authorization, X-Requested-With, Content-Type, Accept';
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # 4. 处理复杂的跨域请求

    如果前端的跨域请求涉及复杂请求(例如使用 PUT, DELETE 方法或自定义请求头),浏览器会发出一个 预检请求(Preflight Request)。这是一个 OPTIONS 请求,用于确定服务端是否允许跨域。

    你需要配置 Nginx 来正确响应这些 OPTIONS 请求。

    server {
        listen 80;
        server_name api.example.com;
    
        location / {
            if ($request_method = OPTIONS) {
                add_header 'Access-Control-Allow-Origin' 'https://app.example.com';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'Origin, Authorization, X-Requested-With, Content-Type, Accept';
                return 204;  # 对于 OPTIONS 请求,直接返回成功的空响应
            }
    
            proxy_pass http://backend_service;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    # 总结:

    你应该在以下情况配置 Nginx 跨域:

    • 当 Nginx 作为静态资源服务器,资源需要被其他域访问时。
    • 当 Nginx 代理不同域的 API 服务,需要允许跨域访问时。
    • 前后端分离的架构中,前端需要请求不同域名的后端 API 服务时。
    • 处理复杂的跨域请求,需要 Nginx 来正确响应 OPTIONS 预检请求时。

    通常来说,Nginx 配置跨域主要是在后端服务无法正确处理 CORS 头的情况下,或者你希望集中管理跨域策略时使用。

    微信 支付宝
    上次更新: 2024/09/11, 21:55:58

    ← 搭建属于自己的云笔记——leanote 从0到1搭建支付和发卡系统→

    最近更新
    01
    shell脚本模块集合
    05-13
    02
    生活小技巧(认知版)
    04-29
    03
    生活小技巧(防骗版)
    04-29
    更多文章>
    Theme by Vdoing | Copyright © 2019-2025 | 点击查看十年之约 | 鄂ICP备2024072800号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式