Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross-Origin Resource Sharing Multiple Sites

I have the following site which contains css/js/images/etc:

global.mysite.com

The __init__.py of the site has the following:

from flask import Flask
from flask.ext.cors import CORS

app = Flask('web')
CORS(app)

I am able to load the resources from another site (we will call it siteA) no problem. Until I attempt to use a 2nd site (siteB) on the same machine, I get the following error:

Font from origin 'http://global.mysite.com' has been blocked from loading by Cross-Origin Resource Sharing policy: The 'Access-Control-Allow-Origin' header has a value 'http://siteA.mysite.com' that is not equal to the supplied origin. Origin 'http://siteB.mysite.com' is therefore not allowed access.

Is there something I need to configure in the CORS aspect of the site, or perhaps a parameter in the __init__.py that I need to add in order allow multiple sites?

This also might look like some sort of caching issue. If so, any thoughts to resolve this?

If you need more info, please feel free to comment.

like image 511
CodeLikeBeaker Avatar asked May 28 '26 19:05

CodeLikeBeaker


1 Answers

I have never used CORS extension, but it looks weird since you need to run the app with it. Making impossible to used other extension like Flask-SocketIO

This decorator works on any route and it does not require any extra extension.

from datetime import timedelta
from flask import make_response, request, current_app
from functools import update_wrapper


def crossdomain(origin=None, methods=None, headers=None,
                max_age=21600, attach_to_all=True,
                automatic_options=True):
    if methods is not None:
        methods = ', '.join(sorted(x.upper() for x in methods))
    if headers is not None and not isinstance(headers, basestring):
        headers = ', '.join(x.upper() for x in headers)
    if not isinstance(origin, basestring):
        origin = ', '.join(origin)
    if isinstance(max_age, timedelta):
        max_age = max_age.total_seconds()

    def get_methods():
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']

    def decorator(f):
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp

        f.provide_automatic_options = False
        return update_wrapper(wrapped_function, f)
    return decorator

And use it

@app.route('/my_service')
@crossdomain(origin='*')
def my_service():
    return jsonify(foo='cross domain ftw')
like image 59
CESCO Avatar answered May 31 '26 11:05

CESCO



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!