Flask 开启跨域

安装 flask-cors

pip install flask-cors

设置允许跨域

开启全局允许跨域

示例

from flask_cors import CORS
CORS(app, supports_credentials=True)

CORS 的参数

参数 类型 Head字段 说明 默认
resources 字典、迭代器或字符串 全局配置允许跨域的API接口 全部
origins 列表、字符串或正则表达式 Access-Control-Allow-Origin 配置允许跨域访问的源,* 表示全部允许 *
methods 列表、字符串 Access-Control-Allow-Methods 配置跨域支持的请求方式,如:GET、POST [GET,HEAD,POST,OPTIONS,PUT,PATCH,DELETE]
expose_headers 列表、字符串 Access-Control-Expose-Headers 自定义请求响应的Head信息 None
allow_headers 列表、字符串或正则表达式 Access-Control-Request-Headers 配置允许跨域的请求头 *
supports_credentials 布尔值 Access-Control-Allow-Credentials 是否允许请求发送cookie,False是不允许,True是允许 False
max_age 整数、字符串 Access-Control-Max-Age 预检请求的有效时长 None

设置单条路由允许跨域

示例

from flask_cors import *

@app.route('/')
@cross_origin(supports_credentials=True)
def hello():
    name = request.args.get("name", "World")
    return f'Hello, {name}!'

cross_origin 的参数

装饰器参数 类型 Head字段 说明 默认
resources 字典、迭代器或字符串 全局配置允许跨域的API接口 全部
origins 列表、字符串或正则表达式 Access-Control-Allow-Origin 配置允许跨域访问的源,* 表示全部允许 *
methods 列表、字符串 Access-Control-Allow-Methods 配置跨域支持的请求方式,如:GET、POST [GET,HEAD,POST,OPTIONS,PUT,PATCH,DELETE]
expose_headers 列表、字符串 Access-Control-Expose-Headers 自定义请求响应的Head信息 None
allow_headers 列表、字符串或正则表达式 Access-Control-Request-Headers 配置允许跨域的请求头 *
supports_credentials 布尔值 Access-Control-Allow-Credentials 是否允许请求发送cookie,False是不允许,True是允许 False
max_age 整数、字符串 Access-Control-Max-Age 预检请求的有效时长 None

注意事项

关于发送Cookie

CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。

CORS(app, supports_credentials=True)

另一方面,开发者必须在AJAX请求中打开withCredentials属性。

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。

CORES(app,origins = ['example1','example2'])

同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

关于预检

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错

"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。
除了Origin字段,"预检"请求的头信息包括两个特殊字段。

  • Access-Control-Request-Method
    该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT
  • Access-Control-Request-Headers
    该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header

服务器收到"预检"请求以后,检查了OriginAccess-Control-Request-MethodAccess-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

拓展

在预检的时候,OPTIONS的请求不会携带cookie和请求的参数,正式请求才会携带Cookie、参数。

postman 模拟跨域请求

  1. 在请求头添加
origin = 127.0.0.1
  1. 查看返回的请求头信息中,是否包含允许跨域信息
Access-Control-Allow-Origin = 127.0.0.1
Access-Control-Allow-Credentials = true
Vary = Origin
posted @ 2021-04-28 14:04  JunCode  阅读(5107)  评论(0编辑  收藏  举报