CORS - Cross-origin resource sharing - 跨域资源共享

什么是CORS

  • 允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制

简单请求(Simple requests)和预检请求(Preflighted requests)

  • 满足以下全部条件的请求为简单请求,不满足任意一点的请求都是预检请求
  • 请求方法如下:
  1. GET
  2. HEAD
  3. POST
  • 请求头仅包含如下:
  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  • Content-Type 仅支持如下三种:
  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

简单请求发送流程

  • 请求头中携带Origin该字段表明自己来自哪个域,如果请求头中的Origin在服务器接受范围内,则返回如下头
  • 如果请求跨域,则响应头中应包含Access-Control-Allow-Origin
响应头 作用 备注
Access-Control-Allow-Origin 服务器接受的域 *值为接受所有域
Access-Control-Allow-Credentials 是否接受Cooike 可选
Access-Control-Expose-Headers 默认情况下,xhr只能拿到如下响应头:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified;如果有需要获取其他头,需在此指定 可选

预检请求发送流程

  • OPTIONS 请求发起,携带如下请求头
请求头 作用 备注
Origin 表明此请求来自哪个域 必选
Access-Control-Request-Method 此次请求使用方法 必选
Access-Control-Request-Headers 此次请求使用的头 必选
  • OPTION 接受响应阶段,携带如下响应头
响应头 作用 备注
Access-Control-Allow-Origin 同简单请求 必选
Access-Control-Allow-Methods 告诉浏览器,服务器接受得跨域请求方法 必选
Access-Control-Allow-Headers 返回所有支持的头部,当request有Access-Control-Request-Headers时,该响应头必然回复 必选
Access-Control-Allow-Credentials 同简单请求 可选
Access-Control-Max-Age OPTION请求缓存时间,单位s 可选
  • 主请求阶段
请求头 作用 备注
Origin 表明此请求来自哪个域 -
  • 主请求响应阶段
响应头 作用 备注
Access-Control-Allow-Origin 当前服务器接受的域 -

Django支持

1,INSTALLED_APPS 中添加 corsheaders
2,MIDDLEWARE 中添加 corsheaders.middleware.CorsMiddleware
  位置尽量靠前,官方建议 ‘django.middleware.common.CommonMiddleware’ 上方

3,CORS_ORIGIN_ALLOW_ALL  布尔值  如果为True 白名单不启用 
4,CORS_ORIGIN_WHITELIST =[
    "https://example.com"
    ] 
5, CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    )
6, CORS_ALLOW_HEADERS = (
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    )
7, CORS_PREFLIGHT_MAX_AGE  默认 86400s

# 8:有没有一些特殊的自定义响应头,需要ajax那边从响应头取值的,一般不用配置,如果你写了一个自定义的头前端要拿,那就配置
8, CORS_EXPOSE_HEADERS  []

# 9:告诉浏览器到底要不要把跨域的cookie送上来,默认不要,跨域的cookie不要
9, CORS_ALLOW_CREDENTIALS  布尔值, 默认False