Flask-CORS跨域请求
简单用法
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!
特定资源的CORS
可以将特定的资源最为字典传入resources,将路径映射到一组选项,
注意:由于多个正则表达式可能匹配一个资源,所以首先按长度(从最长到最短)对正则表达式排序,以便于尝试匹配最特定的正则表达式。
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
@app.route("/api/v1/users")
def list_users():
return "user example"
通过装饰器指定特定的资源CORS
只需在对Flask的`@ app.route(..)`的调用下方 添加`@cross_origin()`,即可在给定路线上使用CORS。
@app.route("/")
@cross_origin()
def helloWorld():
return "Hello, cross-origin-world!"
将CORS与Cookie一起使用
默认情况下,由于Flask-CORS具有潜在的安全隐患,因此它不允许跨站点提交Cookie。如果您希望启用跨站点Cookie,则可能希望添加某种 CSRF 保护,以确保您和用户的安全。
要允许跨源发出Cookie或经过身份验证的请求,只需将`supports_credentials`选项设置为True即可。例如
from flask import Flask, session
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
@app.route("/")
def helloWorld():
return "Hello, %s" % session['username']
将CORS与蓝图一起使用
Flask-CORS开箱即用的支持蓝图。只需将一个蓝图实例传递给CORS扩展,一切都将正常工作。
api_v1 = Blueprint('API_v1', __name__)
CORS(api_v1) # enable CORS on the API_v1 blue print
@api_v1.route("/api/v1/users/")
def list_users():
'''
Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set. The expected result is as follows:
$ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ \
--header Origin:www.examplesite.com
HTTP/1.0 200 OK
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: *
Content-Length: 21
Content-Type: application/json
Date: Sat, 09 Aug 2014 00:26:41 GMT
Server: Werkzeug/0.9.4 Python/2.7.8
{
"success": true
}
'''
return jsonify(user="joe")
@api_v1.route("/api/v1/users/create", methods=['POST'])
def create_user():
'''
Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set.
Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/api/v1/users/create \
--header Access-Control-Request-Method:POST \
--header Access-Control-Request-Headers:Content-Type \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT
$ curl --include -X POST http://127.0.0.1:5000/api/v1/users/create \
--header Content-Type:application/json \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 21
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:04 GMT
{
"success": true
}
'''
return jsonify(success=True)
public_routes = Blueprint('public', __name__)
@public_routes.route("/")
def helloWorld():
'''
Since the path '/' does not match the regular expression r'/api/*',
this route does not have CORS headers set.
'''
return '''<h1>Hello CORS!</h1> Read about my spec at the
<a href="http://www.w3.org/TR/cors/">W3</a> Or, checkout my documentation
on <a href="https://github.com/corydolphin/flask-cors">Github</a>'''
logging.basicConfig(level=logging.INFO)
app = Flask('FlaskCorsBlueprintBasedExample')
app.register_blueprint(api_v1)
app.register_blueprint(public_routes)
if __name__ == "__main__":
app.run(debug=True)
例子
使用CORS扩展
# One of the simplest configurations. Exposes all resources matching /api/* to
# CORS and allows the Content-Type header, which is necessary to POST JSON
# cross origin.
CORS(app, resources=r'/api/*')
@app.route("/")
def helloWorld():
"""
Since the path '/' does not match the regular expression r'/api/*',
this route does not have CORS headers set.
"""
return '''
<html>
<h1>Hello CORS!</h1>
<h3> End to end editable example with jquery! </h3>
<a class="jsbin-embed" href="http://jsbin.com/zazitas/embed?js,console">JS Bin on jsbin.com</a>
<script src="//static.jsbin.com/js/embed.min.js?3.35.12"></script>
</html>
'''
@app.route("/api/v1/users/")
def list_users():
"""
Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set. The expected result is as follows:
$ curl --include -X GET http://127.0.0.1:5000/api/v1/users/ \
--header Origin:www.examplesite.com
HTTP/1.0 200 OK
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Origin: *
Content-Length: 21
Content-Type: application/json
Date: Sat, 09 Aug 2014 00:26:41 GMT
Server: Werkzeug/0.9.4 Python/2.7.8
{
"success": true
}
"""
return jsonify(user="joe")
@app.route("/api/v1/users/create", methods=['POST'])
def create_user():
"""
Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set.
Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/api/v1/users/create \
--header Access-Control-Request-Method:POST \
--header Access-Control-Request-Headers:Content-Type \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT
$ curl --include -X POST http://127.0.0.1:5000/api/v1/users/create \
--header Content-Type:application/json \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 21
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:04 GMT
{
"success": true
}
"""
return jsonify(success=True)
@app.route("/api/exception")
def get_exception():
"""
Since the path matches the regular expression r'/api/*', this resource
automatically has CORS headers set.
Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/exception \
--header Access-Control-Request-Method:POST \
--header Access-Control-Request-Headers:Content-Type \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT
"""
raise Exception("example")
@app.errorhandler(500)
def server_error(e):
logging.exception('An error occurred during a request. %s', e)
return "An internal error occured", 500
if __name__ == "__main__":
app.run(debug=True)
使用cross_origin装饰器
@app.route("/", methods=['GET'])
@cross_origin()
def helloWorld():
'''
This view has CORS enabled for all domains, representing the simplest
configuration of view-based decoration. The expected result is as
follows:
$ curl --include -X GET http://127.0.0.1:5000/ \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 184
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:29:56 GMT
<h1>Hello CORS!</h1> Read about my spec at the
<a href="http://www.w3.org/TR/cors/">W3</a> Or, checkout my documentation
on <a href="https://github.com/corydolphin/flask-cors">Github</a>
'''
return '''<h1>Hello CORS!</h1> Read about my spec at the
<a href="http://www.w3.org/TR/cors/">W3</a> Or, checkout my documentation
on <a href="https://github.com/corydolphin/flask-cors">Github</a>'''
@app.route("/api/v1/users/create", methods=['GET', 'POST'])
@cross_origin(allow_headers=['Content-Type'])
def cross_origin_json_post():
'''
This view has CORS enabled for all domains, and allows browsers
to send the Content-Type header, allowing cross domain AJAX POST
requests.
Browsers will first make a preflight request to verify that the resource
allows cross-origin POSTs with a JSON Content-Type, which can be simulated
as:
$ curl --include -X OPTIONS http://127.0.0.1:5000/api/v1/users/create \
--header Access-Control-Request-Method:POST \
--header Access-Control-Request-Headers:Content-Type \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: POST, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Content-Length: 0
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:22 GMT
$ curl --include -X POST http://127.0.0.1:5000/api/v1/users/create \
--header Content-Type:application/json \
--header Origin:www.examplesite.com
>> HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 21
Access-Control-Allow-Origin: *
Server: Werkzeug/0.9.6 Python/2.7.9
Date: Sat, 31 Jan 2015 22:25:04 GMT
{
"success": true
}
'''
return jsonify(success=True)
if __name__ == "__main__":
app.run(debug=True)