首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Web服务器-Nginx解决跨域问题

Web服务器-Nginx解决跨域问题

作者头像
运维小路
发布于 2025-04-20 15:49:31
发布于 2025-04-20 15:49:31
40300
代码可运行
举报
文章被收录于专栏:运维小路运维小路
运行总次数:0
代码可运行

作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们上一大章介绍了Kubernetes的知识,本章节我们进入中间件的讲解,这里会包含很多不同的类型组件,中间件的第一个大类我这里定义的是Web服务器。由于目前使用最广泛的Web服务器是Nginx,所以我们这里的讲解主要以Nginx服务器为主。

跨域介绍

跨域(Cross-Origin Resource Sharing,简称CORS)是指在一个域下的网页尝试请求另一个域下的资源时发生的情况。这里的“域”是指协议(如HTTP或HTTPS)、域名(如example.com)和端口号(如80或443)的组合。

在Web开发中,同源策略(Same-Origin Policy)是一种重要的安全措施,它限制了从一个源加载的文档或脚本如何与另一个源的资源进行交互。这个策略可以防止恶意网站读取另一个网站的数据,但它也限制了合法跨域请求的能力。

原始域

目标域

协议

端口

是否跨域

原因

a.com

a.com

HTTP

80

域名、协议、端口都相同

a.com

a.com

HTTPS

443

域名、协议、端口都相同

a.com

b.com

HTTP

80

域名不同

a.com

a.com

HTTP

8080

端口不同

a.com

a.com

HTTPS

80

协议不同

构建跨域

1.构建一个后端服务

Python启动一个Web服务,监听在8000端口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        response = {'message': 'Hello, world!'}
        self.wfile.write(str(response).encode())

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print("Server started at localhost:8000")
    httpd.serve_forever()

if __name__ == '__main__':
    run()

2.使用静态网页去访问这个接口

通过Nginx配置,让我可以访问到这个页面,然后页面有一个连接点击会去请求通过Nginx转发的服务后端服务。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Frontend</title>
</head>
<body>
    <h1>My Simple Static Web Page</h1>
    <button id="loadData">Load Data from Backend</button>
    <div id="data"></div>

    <script>
        document.getElementById('loadData').addEventListener('click', function() {
            fetch('https://chenhong.fun/api')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('data').textContent = data.message;
                })
                .catch(error => console.error('Error:', error));
        });
    </script>
</body>
</html>

Nginx配置了静态网页和一个api接口(转接到后端服务)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    location / {
        root /home/static;
        index index.html;
    }
    location /api {
        proxy_pass http://localhost:8000;
        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;
    }

3.访问触发跨越

这里我们复用了前面的https配置,为了触发跨域,所以我这里使用IP访问。

当前域:IP

目标域:域名

我这个是简单请求,所以后端会收到请求但是浏览器不会响应数据,在某些复杂的请求里面,请求都不会转发到后端,因为浏览器跨域保护,导致请求未向后端转发。

在调试里面的Console里面也会有跨域提示。

4.修改Nginx配置

通过调整Nginx配置解决跨域问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    location /api {
        proxy_pass http://localhost:8000;
        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;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
        if ($request_method = 'OPTIONS') {
           return 204;
        }

重载Nginx以后,再重新通过IP访问,后端接口使用域名就不会触发跨域问题。

5.从后端代码层面界面解决跨域问题

就是不修改Nginx配置,而直接从后端来代码来实现,代码改成这样,则不会有跨域提示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from http.server import BaseHTTPRequestHandler, HTTPServer
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        response = {'message': 'Hello, world!'}
        self.wfile.write(str(response).encode())
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
        self.end_headers()
def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print("Server started at localhost:8000")
    httpd.serve_forever()
if __name__ == '__main__':
    run()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维小路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档