如何让Django/DRF支持无末尾斜杠URL且不触发重定向
解决Django/DRF无末尾斜杠URL请求404或重定向问题
问题原因
Django默认开启APPEND_SLASH = True配置,当收到无末尾斜杠且无法匹配现有路由的请求时,会自动301重定向到带斜杠的路径;如果手动关闭该配置为False,Django不会做自动补全匹配,若你的路由定义时带了末尾斜杠,无斜杠的请求就会直接返回404。
解决方案
方案1:路由同时兼容带/不带尾斜杠
两种常用实现:- 通用Django路由:将
path路由改为用re_path正则匹配,标记斜杠为可选:
from django.urls import re_path # ? 表示前面的斜杠可出现0或1次,两种格式请求都能匹配 re_path(r'^api/items/?$', views.item_view, name='item-list')- DRF专属路由:如果你使用DRF的
DefaultRouter/SimpleRouter生成路由,可直接修改trailing_slash参数关闭自动加尾斜杠的逻辑:
如果需要同时兼容两种格式,优先使用第一种正则实现。from rest_framework.routers import DefaultRouter # 生成的所有路由默认不带尾斜杠 router = DefaultRouter(trailing_slash=False) router.register('items', ItemViewSet)- 通用Django路由:将
方案2:全局中间件统一处理
自定义全局中间件,在路由匹配前统一处理尾斜杠,无需挨个修改路由:
将该中间件添加到from django.http import HttpResponsePermanentRedirect from django.utils.deprecation import MiddlewareMixin class SlashAdaptMiddleware(MiddlewareMixin): def process_request(self, request): # 示例:统一去掉所有请求的尾斜杠,需配合 APPEND_SLASH = False 使用 if request.path != '/' and request.path.endswith('/'): return HttpResponsePermanentRedirect(request.path.rstrip('/'))settings.py的MIDDLEWARE列表最顶部即可生效。方案3:前后端统一规范
若不想修改后端逻辑,保持APPEND_SLASH = True默认配置,要求前端发起请求时统一带末尾斜杠;注意*非幂等请求(POST/PUT/DELETE)*跟随重定向时,部分HTTP客户端会自动将请求转为GET导致参数丢失,这种场景不推荐用该方案。
最优实践建议
API类接口优先配置兼容两种尾斜杠格式的路由,同时前后端约定统一的URL规范,从根源避免重定向拖慢响应或404问题。普通页面路由可保留默认重定向逻辑,不影响SEO效果。
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

