安装django-cors-headers

使用pip安装

1
pip install django-cors-headers

官方文档:adamchainz/django-cors-headers: Django app for handling the server headers required for Cross-Origin Resource Sharing (CORS) (github.com)

中文文档:django-cors-headers - Lowell - 博客园 (cnblogs.com)

配置

在APP中注册

1
2
3
4
5
INSTALLED_APPS = [
    ...,
    "corsheaders",
    ...,
]

添加中间件

1
2
3
4
5
6
MIDDLEWARE = [
    ...,
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...,
]

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django’s CommonMiddleware or Whitenoise’s WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.

设置中间件的位置尽可能要前,防止其他中间件修改了CORS headers

配置允许通过的域名

通过配置CORS_ALLOWED_ORIGINS添加通过的域名

1
2
3
4
5
6
CORS_ALLOWED_ORIGINS = [
    "https://example.com",
    "https://sub.example.com",
    "http://localhost:8080",
    "http://127.0.0.1:9000",
]

也可以使用正则表达式,配置CORS_ALLOWED_ORIGIN_REGEXES,即可

1
2
3
CORS_ALLOWED_ORIGIN_REGEXES = [
    r"^https://\w+\.example\.com$",
]

爱特合作的情况多半是后端部署上服务器,然后前端在本地对接后,打包代码后发给后端部署,所以需要设置一下允许内网IP允许跨域。

1
2
3
4
5
if DEBUG:
    CORS_ALLOWED_ORIGIN_REGEXES = [
        # 允许内网IP及所有端口,用于调试
        r"^http://((127\.0\.0\.1)|(localhost)|(10\.\d{1,3}\.\d{1,3}\.\d{1,3})|(172\.((1[6-9])|(2\d)|(3[01]))\.\d{1,3}\.\d{1,3})|(192\.168\.\d{1,3}\.\d{1,3}))(:\d+){0,1}$",
    ]

注意上线之后,需要将域名 / IP + 端口 添加到白名单内

允许跨域认证

配置CORS_ALLOW_CREDENTIALS

1
CORS_ALLOW_CREDENTIALS = True

如果不配置为True,则跨域的情况下,使用Cookie和Authorization头等认证方式,是无法通过认证的。

如果发现配置了,还是无法在跨域的情况下认证,请检查以下几点:

  1. CORS_ORIGIN_ALLOW_ALL是否为False

  2. Nginx是否修改了CORS的header

a1c05a9418ef7eb96af7f784cb8e9361.webp

由于在CORS_ALLOW_CREDENTIALS开启的情况下,Access-Control-Allow-Origin不能为*,必须为域名,否则会被浏览器拦截。

碎碎念

跨域的要求是,如果 域名 、 协议 、 端口,任何一个不同都算跨域。如果在服务器上通过Nginx反向代理,实现了前端地址为https://www.example.com/,后端地址为https://www.example.com/api/就不需要考虑跨域的问题了。

个人看法:CORS_ORIGIN_ALLOW_ALL还是不要开启的好,除非是API服务提供商