cors.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from datetime import timedelta
  4. from flask import make_response, request, current_app
  5. from functools import update_wrapper
  6. def crossdomain(
  7. origin=None,
  8. methods=None,
  9. headers=None,
  10. expose_headers=None,
  11. max_age=21600,
  12. attach_to_all=True,
  13. automatic_options=True,
  14. credentials=False,
  15. ):
  16. """
  17. https://web.archive.org/web/20190128010149/http://flask.pocoo.org/snippets/56/
  18. """
  19. if methods is not None:
  20. methods = ", ".join(sorted(x.upper() for x in methods))
  21. if headers is not None and not isinstance(headers, str):
  22. headers = ", ".join(x.upper() for x in headers)
  23. if expose_headers is not None and not isinstance(expose_headers, str):
  24. expose_headers = ", ".join(x.upper() for x in expose_headers)
  25. if not isinstance(origin, str):
  26. origin = ", ".join(origin)
  27. if isinstance(max_age, timedelta):
  28. max_age = max_age.total_seconds()
  29. def get_methods():
  30. if methods is not None:
  31. return methods
  32. options_resp = current_app.make_default_options_response()
  33. return options_resp.headers["allow"]
  34. def decorator(f):
  35. def wrapped_function(*args, **kwargs):
  36. if automatic_options and request.method == "OPTIONS":
  37. resp = current_app.make_default_options_response()
  38. else:
  39. resp = make_response(f(*args, **kwargs))
  40. if not attach_to_all and request.method != "OPTIONS":
  41. return resp
  42. h = resp.headers
  43. h["Access-Control-Allow-Origin"] = origin
  44. h["Access-Control-Allow-Methods"] = get_methods()
  45. h["Access-Control-Max-Age"] = str(max_age)
  46. if credentials:
  47. h["Access-Control-Allow-Credentials"] = "true"
  48. if headers is not None:
  49. h["Access-Control-Allow-Headers"] = headers
  50. if expose_headers is not None:
  51. h["Access-Control-Expose-Headers"] = expose_headers
  52. return resp
  53. f.provide_automatic_options = False
  54. return update_wrapper(wrapped_function, f)
  55. return decorator