You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何将hostname/endpoint请求重定向至api.hostname/endpoint

问题根因

你之前在urlpatterns里加规则不生效,核心原因是hostname(根域)和api.hostname(API子域)是两个独立的服务入口,插件发往根域/endpoint的请求,根本不会路由到你API服务的Django路由层,你在API服务的路由表里写再多规则都碰不到这些请求,自然达不到效果。

可行实现方案

方案1:反向代理层转发(首推,性能最好,无跨域问题)

如果你的服务前面挂了Nginx、Caddy这类反向代理,直接在根域的代理配置里加匹配规则,把对应路径的流量直接转到API子域,完全不用改业务代码。

  • Nginx配置(放到根域对应的server块内):
# 按你插件实际请求的路径改匹配规则,下面示例匹配三类接口路径
location ~ ^/(user/info|order/list|upload/.*)$ {
    proxy_pass https://api.hostname$request_uri;
    # 透传必要请求头,避免鉴权、IP识别异常
    proxy_set_header Host api.hostname;
    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;
}
  • 如果用Caddy,配置更简洁,在根域配置块加:
hostname.com {
    # 保留你原来根域站点的所有配置
    handle_path /user/* /order/* /upload/* {
        reverse_proxy https://api.hostname.com
    }
}

这个方案在流量入口层就完成转发,请求根本不会落到根域的业务服务上,性能损耗可以忽略,也不会触发浏览器/插件的跨域限制。

方案2:根域服务配置重定向(不想动代理时选)

如果根域本身也跑在Django服务上,直接在根域对应的Django项目的根路由里加重定向规则就行——注意别再写到API子域的路由表里了,之前就是配错了位置。
配置示例(根域的urls.py):

from django.views.generic import RedirectView
from django.urls import re_path

urlpatterns = [
    # 先写你原来根域的其他路由
    # 匹配需要转发的接口路径,用307状态码保留原请求方法和请求体,避免POST请求变GET丢参数
    re_path(
        r'^(?P<api_path>user/.*|order/.*|upload/.*)$',
        RedirectView.as_view(
            url='https://api.hostname/%(api_path)s',
            permanent=False,
            query_string=True
        ),
        name='api_redirect'
    ),
]

注意这个方案的局限:如果插件没有做跨域适配,重定向后可能触发CORS拦截,而且绝对不要用301/302状态码,这两个状态码会把POST/PUT类请求改成GET,请求体直接丢失。

方案3:API服务绑定多域名(零转发开销)

如果你能改DNS和服务配置,可以直接把根域也解析到API服务的服务器IP,在API服务的域名绑定里加上根域,再写个简单的中间件做路径隔离就行,连转发都不用。
首先改Django配置:

# settings.py
ALLOWED_HOSTS = ['api.hostname', 'hostname']

然后加个简单的中间件处理路由:

# middlewares.py
class HostForwardMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 只处理根域过来的API路径请求,其他根域请求按需处理
        valid_api_prefix = ('/user/', '/order/', '/upload/')
        if request.get_host() == 'hostname':
            if request.path.startswith(valid_api_prefix):
                # 直接走API服务的原有逻辑处理
                request.META['HTTP_HOST'] = 'api.hostname'
            else:
                # 非API路径的根域请求,可转到对应服务或返回404
                pass
        return self.get_response(request)

最后把这个中间件加到settings.py的MIDDLEWARE列表最前面就行。这个方案相当于API服务同时响应两个域名的指定路径请求,没有额外转发开销,但是要注意做好路径隔离,别把根域的其他正常请求也拦到API逻辑里。

避坑提醒:所有转发规则都要记得保留原请求的query参数和请求体,不然插件请求会丢参数。

内容的提问来源于stack exchange,提问作者humanbeing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:06:24