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

Safari/iOS请求Django+Next.js项目接口返回403 其余浏览器运行正常

问题根因&解决方案

这个问题是Safari浏览器的特性和Django/DRF默认配置冲突导致的,按优先级排查解决即可:

1. 重定向丢认证头(最高概率)

Django默认开启APPEND_SLASH配置,当你请求的接口URL没有带末尾斜杠时(比如请求/api/get_categories而不是/api/get_categories/),Django会自动返回301重定向到带斜杠的地址。Chrome在重定向时会保留Authorization请求头,但Safari会在重定向时自动删除所有自定义请求头,导致重定向后的请求没有携带token,返回403。

  • 解决方法1:前端请求时统一给所有接口URL加上末尾斜杠,避免触发重定向
  • 解决方法2:在Django settings.py中添加配置APPEND_SLASH = False,关闭自动补全斜杠逻辑,同步调整所有接口的URL定义即可。

2. OPTIONS预检请求被拦截

跨域请求下,Safari会主动对带自定义头(比如Authorization)的请求先发送OPTIONS预检请求,DRF默认的权限校验会要求OPTIONS请求也携带认证信息,直接返回403,导致后续实际请求不会发送。

  • 解决方法:自定义DRF权限类,豁免OPTIONS请求的认证校验:
# 自定义权限类
from rest_framework.permissions import IsAuthenticated

class ExemptOptionsPermission(IsAuthenticated):
    def has_permission(self, request, view):
        if request.method == "OPTIONS":
            return True
        return super().has_permission(request, view)

然后替换settings.py中的权限配置:

REST_FRAMEWORK = {
    # 其余原有配置保留
    'DEFAULT_PERMISSION_CLASSES': (
        '你的应用路径.ExemptOptionsPermission',
    )
}

3. 跨域配置不符合Safari要求

如果是前后端分离部署,要确保跨域配置适配Safari规则:

  • 必须安装django-cors-headers包处理跨域
  • 不要用*作为允许的源地址,要显式配置前端域名,示例配置:
# settings.py
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
    "https://你的前端域名.com",
    "http://localhost:8080", # 本地开发地址
]
CORS_ALLOW_HEADERS = [
    # 其余默认头保留
    "authorization",
    "content-type",
]

验证方法

打开Safari开发者工具的「网络」面板,勾选「保留日志」选项,重新发起请求,就能看到完整的请求链路:如果有301重定向就是问题1,如果OPTIONS请求返回403就是问题2。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:54:03