add a decorator for CORS.
This commit is contained in:
parent
c5cdcf0f95
commit
49fb34ca2b
50
examples/cors.html
Normal file
50
examples/cors.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Cors Example</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var xhr1 = new XMLHttpRequest();
|
||||
|
||||
xhr1.onload = function () {
|
||||
console.log(xhr1.responseText)
|
||||
};
|
||||
|
||||
xhr1.open('GET', 'http://127.0.0.1:8000/');
|
||||
xhr1.send();
|
||||
|
||||
var xhr2 = new XMLHttpRequest();
|
||||
|
||||
xhr2.onload = function () {
|
||||
console.log(xhr2.responseText)
|
||||
};
|
||||
|
||||
xhr2.open('GET', 'http://127.0.0.1:8000/t2');
|
||||
xhr2.send();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var ws = new WebSocket('ws://127.0.0.1:8000/feed'),
|
||||
messages = document.createElement('ul');
|
||||
ws.onmessage = function (event) {
|
||||
var messages = document.getElementsByTagName('ul')[0],
|
||||
message = document.createElement('li'),
|
||||
content = document.createTextNode('Received: ' + event.data);
|
||||
message.appendChild(content);
|
||||
messages.appendChild(message);
|
||||
};
|
||||
document.body.appendChild(messages);
|
||||
window.setInterval(function () {
|
||||
var data = 'bye!';
|
||||
ws.send(data);
|
||||
var messages = document.getElementsByTagName('ul')[0],
|
||||
message = document.createElement('li'),
|
||||
content = document.createTextNode('Sent: ' + data);
|
||||
message.appendChild(content);
|
||||
messages.appendChild(message);
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
31
examples/cors_example.py
Normal file
31
examples/cors_example.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from sanic import Sanic
|
||||
from sanic import response
|
||||
|
||||
app = Sanic(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
@response.cors()
|
||||
async def test(request):
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
@app.route("/t2")
|
||||
@response.cors()
|
||||
def test2(request):
|
||||
return response.json({"test": True})
|
||||
|
||||
|
||||
@app.websocket('/feed')
|
||||
@response.cors()
|
||||
async def feed(request, ws):
|
||||
while True:
|
||||
data = 'hello!'
|
||||
print('Sending: ' + data)
|
||||
await ws.send(data)
|
||||
data = await ws.recv()
|
||||
print('Received: ' + data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="0.0.0.0", port=8000)
|
|
@ -1,5 +1,7 @@
|
|||
from mimetypes import guess_type
|
||||
from os import path
|
||||
from functools import wraps
|
||||
from inspect import isawaitable
|
||||
|
||||
try:
|
||||
from ujson import dumps as json_dumps
|
||||
|
@ -9,6 +11,7 @@ except:
|
|||
from aiofiles import open as open_async
|
||||
|
||||
from sanic.cookies import CookieJar
|
||||
from sanic.constants import HTTP_METHODS
|
||||
|
||||
COMMON_STATUS_CODES = {
|
||||
200: b'OK',
|
||||
|
@ -427,3 +430,45 @@ def redirect(to, headers=None, status=302,
|
|||
status=status,
|
||||
headers=headers,
|
||||
content_type=content_type)
|
||||
|
||||
|
||||
def cors(origin=None, allow_methods=None):
|
||||
if isinstance(allow_methods, (list, tuple, set)):
|
||||
allow_methods = ', '.join(
|
||||
filter(
|
||||
lambda x: x in HTTP_METHODS,
|
||||
map(
|
||||
lambda x: x.upper(),
|
||||
allow_methods
|
||||
)
|
||||
)
|
||||
)
|
||||
elif allow_methods:
|
||||
raise ValueError('allow_methods must be instance of list, tuple or set.')
|
||||
|
||||
cors_headers = {
|
||||
'Access-Control-Allow-Credentials': 'true',
|
||||
'Access-Control-Allow-Methods': allow_methods or 'GET',
|
||||
'Access-Control-Allow-Origin': origin or '*'
|
||||
}
|
||||
|
||||
def decorator(fn):
|
||||
@wraps(fn)
|
||||
def wrap(*args, **kwargs):
|
||||
res = fn(*args, **kwargs)
|
||||
if isinstance(res, BaseHTTPResponse):
|
||||
res.headers.update(cors_headers)
|
||||
return res
|
||||
elif isawaitable(res):
|
||||
async def make_cors():
|
||||
response = await res
|
||||
response.headers.update(cors_headers)
|
||||
return response
|
||||
|
||||
return make_cors()
|
||||
|
||||
return res
|
||||
|
||||
return wrap
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Reference in New Issue
Block a user