Javascript - No 'Access-Control-Allow-Origin' header is present on the requested resource

后端 未结 7 1774
天命终不由人
天命终不由人 2020-11-27 17:25

I need to send data through XmlHttpRequest from JavaScript to Python server. Because I\'m using localhost, I need to use CORS. I\'m using the Flask framework an

相关标签:
7条回答
  • 2020-11-27 17:47

    The Access-Control-Allow-Origin must be sent by the server, not by you. When you make a call to another domain, the browser checks whether this header is returned by the server. If it isn't, the call fails. I don't know Python, so I don't know how to make your server send this header, or even if you can modify the server at all.

    0 讨论(0)
  • 2020-11-27 17:48

    I have used the solution from Zachary. Works well.

    For those who are wondering where to place the new decorator:

    Just copy the code from the link that Zachary provided and place it in a .py file

    Place it in the folder where your python modules are present(varies based on what system you use and whether or not you are using a virtual environment).

    In your flask app, import the method crossdomain from the newly created python module and use it.

    0 讨论(0)
  • 2020-11-27 17:57

    Old question, but for future googlers with this problem, I solved it (and a few other downstream issues having to do with CORS) for my flask-restful app by adding the following to my app.py file:

    app = Flask(__name__)
    api = Api(app)
    
    @app.after_request
    def after_request(response):
      response.headers.add('Access-Control-Allow-Origin', '*')
      response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
      response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
      return response
    
    
    if __name__ == '__main__':
        app.run()
    
    0 讨论(0)
  • 2020-11-27 17:59

    I got Javascript working with Flask by using this decorator, and adding "OPTIONS" to my list of acceptable methods. The decorator should be used beneath your route decorator, like this:

    @app.route('/login', methods=['POST', 'OPTIONS'])
    @crossdomain(origin='*')
    def login()
        ...
    

    Edit: Link appears to be broken. Here's the decorator I used.

    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):
        """Decorator function that allows crossdomain requests.
          Courtesy of
          https://blog.skyred.fi/articles/better-crossdomain-snippet-for-flask.html
        """
        if methods is not None:
            methods = ', '.join(sorted(x.upper() for x in methods))
        # use str instead of basestring if using Python 3.x
        if headers is not None and not isinstance(headers, basestring):
            headers = ', '.join(x.upper() for x in headers)
        # use str instead of basestring if using Python 3.x
        if not isinstance(origin, basestring):
            origin = ', '.join(origin)
        if isinstance(max_age, timedelta):
            max_age = max_age.total_seconds()
    
        def get_methods():
            """ Determines which methods are allowed
            """
            if methods is not None:
                return methods
    
            options_resp = current_app.make_default_options_response()
            return options_resp.headers['allow']
    
        def decorator(f):
            """The decorator function
            """
            def wrapped_function(*args, **kwargs):
                """Caries out the actual cross domain code
                """
                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)
                h['Access-Control-Allow-Credentials'] = 'true'
                h['Access-Control-Allow-Headers'] = \
                    "Origin, X-Requested-With, Content-Type, Accept, Authorization"
                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
    
    0 讨论(0)
  • 2020-11-27 18:03

    When using python 2.7

    app = Flask(__name__)
    api = Api(app)
    
    @app.after_request
    def after_request(response):
      response.headers.add('Access-Control-Allow-Origin', '*')
      response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
      response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
      return response
    
    
    if __name__ == '__main__':
        app.run()
    

    When running on python3 or ahead, install flask-cors using the command pip install flask-cors The add the following:

    from flask_cors import CORS
    app = Flask(__name__)
    CORS(app)
    
    0 讨论(0)
  • 2020-11-27 18:06

    I have used the flask-cors extension.

    Install using pip install flask-cors

    Then it's simply

    from flask_cors import CORS
    app = Flask(__name__)
    CORS(app)
    

    This will allow all domains

    0 讨论(0)
提交回复
热议问题