使用Nginx代理解决跨域问题并传递请求头的完整指南

 更新时间:2025年01月17日 08:51:24   作者:码农阿豪@新空间代码工作室  
在现代 Web 开发中,跨域资源共享(CORS)是一个常见的问题,当你的前端应用尝试从一个域名请求另一个域名的资源时,浏览器会阻止这种请求,除非目标服务器明确允许跨域访问,本文将详细介绍如何使用 Nginx 作为代理服务器来解决跨域问题,需要的朋友可以参考下

引言

在现代 Web 开发中,跨域资源共享(CORS)是一个常见的问题。当你的前端应用尝试从一个域名请求另一个域名的资源时,浏览器会阻止这种请求,除非目标服务器明确允许跨域访问。为了解决这个问题,开发者通常会使用代理服务器来转发请求,从而绕过浏览器的同源策略。

本文将详细介绍如何使用 Nginx 作为代理服务器来解决跨域问题,并确保前端请求头(如 Cookie、User-Agent、Accept 等)能够正确传递到目标服务器。我们将从 Nginx 的基本配置开始,逐步深入,最终形成一个完整的解决方案。

1. 什么是跨域问题?

跨域问题是由浏览器的同源策略引起的。同源策略要求浏览器只能允许来自同一域名的请求,而阻止来自其他域名的请求。具体来说,如果前端应用的域名是 http://localhost:8080,而目标 API 的域名是 http://travel.yundasys.com:31432,那么浏览器会阻止这种跨域请求。

1.1 跨域问题的表现

当你尝试从前端发起跨域请求时,浏览器会返回类似以下的错误:

Access to XMLHttpRequest at 'http://travel.yundasys.com:31432/interface/orderPhone?txm=320328706913678&type=1' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

1.2 解决跨域问题的常见方法

  • CORS 头配置:在目标服务器上配置 Access-Control-Allow-Origin 头,允许特定域名的跨域请求。
  • JSONP:通过动态创建 <script> 标签绕过跨域限制,但只支持 GET 请求。
  • 代理服务器:使用代理服务器转发请求,从而绕过浏览器的同源策略。

本文将重点介绍如何使用 Nginx 作为代理服务器来解决跨域问题。

2. 使用 Nginx 作为代理服务器

Nginx 是一个高性能的 HTTP 服务器和反向代理服务器。通过配置 Nginx,我们可以将前端的请求转发到目标服务器,并在响应中添加必要的 CORS 头,从而解决跨域问题。

2.1 Nginx 的基本配置

以下是一个简单的 Nginx 配置文件示例:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

在这个配置中,Nginx 监听 80 端口,并将请求转发到本地的 html 目录。

2.2 添加跨域支持

为了支持跨域请求,我们需要在 Nginx 配置中添加以下内容:

server {
    listen       80;
    server_name  localhost;

    # 支持跨域的配置
    add_header 'Access-Control-Allow-Origin' '*';
    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-Expose-Headers' 'Content-Length,Content-Range';

    location / {
        root   html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

在这个配置中,我们添加了 add_header 指令来设置 CORS 头,允许所有域名的跨域请求。

3. 配置 Nginx 代理传递请求头

默认情况下,Nginx 会将客户端(浏览器)发送的请求头(如 Accept、Cookie、User-Agent 等)转发到目标服务器。然而,如果你在 Nginx 配置中显式地设置了某些请求头(如 Host、X-Real-IP 等),可能会覆盖或删除原始请求头。

为了确保所有请求头能够正确传递到目标服务器,我们需要调整 Nginx 配置。

3.1 修改后的 Nginx 配置

以下是修改后的 Nginx 配置,确保所有请求头都被正确传递:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        # 支持跨域的配置
        add_header 'Access-Control-Allow-Origin' '*';
        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-Expose-Headers' 'Content-Length,Content-Range';

        location / {
            root   html;
            index  index.html index.htm;
        }

        # 代理 API 请求
        location /api/ {
            proxy_pass http://travel.yundasys.com:31432/;  # 替换为你的 API 服务器地址

            # 保留原始请求头
            proxy_pass_request_headers on;

            # 设置必要的代理头
            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;

            # 如果需要传递原始 Cookie,确保不覆盖 Cookie 头
            proxy_set_header Cookie $http_cookie;

            # 如果需要传递原始 User-Agent,确保不覆盖 User-Agent 头
            proxy_set_header User-Agent $http_user_agent;

            # 如果需要传递原始 Accept,确保不覆盖 Accept 头
            proxy_set_header Accept $http_accept;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

3.2 关键改动说明

  1. proxy_pass_request_headers on;

    • 这是默认行为,确保所有客户端请求头都被传递到目标服务器。
    • 如果你没有显式覆盖某些请求头,这一步可以省略。
  2. proxy_set_header

    • 使用 proxy_set_header 设置必要的代理头(如 HostX-Real-IP 等)。
    • 对于需要保留的原始请求头(如 CookieUser-AgentAccept),使用 $http_<header_name> 变量传递原始值。
  3. $http_<header_name>

    • $http_cookie:传递原始 Cookie 头。
    • $http_user_agent:传递原始 User-Agent 头。
    • $http_accept:传递原始 Accept 头。

4. 验证请求头是否被正确传递

为了确保请求头被正确传递到目标服务器,你可以通过以下方式验证:

  1. 检查目标服务器的日志

    • 在目标服务器上查看日志,确认接收到的请求头是否与前端发送的一致。
  2. 使用调试工具

    • 在 Nginx 中启用调试日志,查看请求头是否被正确转发:
error_log /var/log/nginx/error.log debug;

在 Nginx 中记录请求头

  • 在 Nginx 配置中添加日志记录,输出请求头:
location /api/ {
    proxy_pass http://travel.yundasys.com:31432/;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # 记录请求头
    add_header X-Debug-Request-Headers "$http_user_agent $http_cookie";
}

5. 前端代码的调整

如果你使用了 Nginx 代理,前端代码中的 url 需要改为代理地址。例如:

// 目标 URL(改为 Nginx 代理地址)
const url = "http://your-nginx-server/api/interface/orderPhone?txm=320328706913678&type=1";

// 请求头
const headers = {
  "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
  "Accept-Language": "zh-CN,zh;q=0.9",
  "Cache-Control": "max-age=0",
  "Connection": "keep-alive",
  "Cookie": "CASTGC=TGT-37528572-jMiSLXk2PqxLEdKk2lxzXfSwgfo5MYa3MdD; SESSION=OTdiOTQ4NDQtY2M2ZC00NmVjLTgwZmItNzMzNDVjZDlmNmU4",
  "DNT": "1",
  "Upgrade-Insecure-Requests": "1",
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
};

// 发起请求
fetch(url, {
  method: "GET", // 请求方法
  headers: headers, // 请求头
  credentials: "include" // 包含 Cookie
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.text(); // 解析响应为文本
  })
  .then(data => {
    console.log("Response data:", data); // 输出响应数据
  })
  .catch(error => {
    console.error("Error:", error); // 捕获错误
  });

6. 总结

通过本文的介绍,我们详细讲解了如何使用 Nginx 作为代理服务器来解决跨域问题,并确保前端请求头能够正确传递到目标服务器。以下是关键点总结:

  1. 跨域问题的本质:浏览器的同源策略阻止了跨域请求。
  2. Nginx 代理的作用:通过代理服务器转发请求,绕过浏览器的同源策略。
  3. Nginx 配置的关键点
    • 使用 add_header 设置 CORS 头。
    • 使用 proxy_set_header 传递原始请求头。
  4. 验证请求头:通过日志和调试工具确保请求头被正确传递。
  5. 前端代码的调整:将目标 URL 改为代理地址。

到此这篇关于使用Nginx代理解决跨域问题并传递请求头的完整指南的文章就介绍到这了,更多相关Nginx解决跨域问题并传递请求头内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Nginx服务安装及软件升级

    Nginx服务安装及软件升级

    这篇文章主要为大家介绍了Nginx服务的安装以及软件升级的步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • Nginx添加ipv6模块以及遇到问题解决方案详解(亲测有效)

    Nginx添加ipv6模块以及遇到问题解决方案详解(亲测有效)

    IPV4日益稀缺,ipv6已经慢慢走上日程,待ipv6在国内普及,使用nginx配置ipv6那是肯定的,下面这篇文章主要给大家介绍了关于Nginx添加ipv6模块以及遇到问题的解决方案,需要的朋友可以参考下
    2022-09-09
  • 详解nginx请求头数据读取流程

    详解nginx请求头数据读取流程

    这篇文章主要介绍了详解nginx请求头数据读取流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 详解nginx 中location和 proxy_pass的匹配规则

    详解nginx 中location和 proxy_pass的匹配规则

    location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如 proxy_pass)会应用在匹配的请求上,这篇文章主要介绍了nginxlocation和proxy_pass的匹配规则,需要的朋友可以参考下
    2025-04-04
  • nginx中url地址重写的实现

    nginx中url地址重写的实现

    本文主要介绍了nginx中url地址重写的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-03-03
  • nginx之限流详解(请求/并发量)

    nginx之限流详解(请求/并发量)

    文章介绍Web运维中使用Nginx的limit_conn和limit_req模块限制IP连接数及请求频率,防范恶意攻击和爬虫,通过$binary_remote_addr或map模块处理代理层IP,设置503错误防止服务器过载
    2025-08-08
  • 利用Nginx反向代理功能解决WEB网站80端口被封的解决方法

    利用Nginx反向代理功能解决WEB网站80端口被封的解决方法

    大陆的网络环境,都在天朝神兽的制度下让我等小P民悲剧一片;动不动就拔网线、封机房;现在更厉害的一招,从网关封杀你的80端口,一旦被封,网站域名就无法访问
    2012-08-08
  • Nginx 负载均衡是什么以及该如何配置

    Nginx 负载均衡是什么以及该如何配置

    这篇文章主要介绍了Nginx 负载均衡是什么以及该如何配置,帮助大家更好的理解和使用Nginx服务器,感兴趣的朋友可以了解下
    2021-01-01
  • Nginx 禁止直接访问目录或文件的操作方法

    Nginx 禁止直接访问目录或文件的操作方法

    Nginx 默认是不允许列出整个目录的,那么需要这样的功能怎么操作呢,下面小编给大家介绍下Nginx 禁止直接访问目录或文件的方法,需要的朋友可以参考下
    2022-10-10
  • k8s部署ingress-nginx的方法步骤

    k8s部署ingress-nginx的方法步骤

    k8s集群服务部署好之后,需要对外提域名访问,这时候就需要ingress-nginx了,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12

最新评论