【问题标题】:Python Flask Cors IssuePython Flask Cors 问题
【发布时间】:2015-04-12 05:11:53
【问题描述】:

我对 Python 有点陌生,但我在使用 Node 应用程序时遇到了同样的问题。我正在向我的本地 Python 服务器发出一个非常标准的 jQuery AJAX 请求:

init: function(callback) {
            var token = _config.get_token();

            $.ajax({
                    url: 'http://localhost:5000/api/ia/v1/user_likes',
                    type: 'POST',
                    contentType: 'application/json',
                    datatype: 'json',
                    data: token
                })
                .done(function(data) {
                    callback(data);
                })
                .fail(function(err) {
                    callback(err);
                });

            callback(token);
        }

我可以确认变量令牌是这样确认的:

Object {access_token: "791415154.2c0a5f7.4d707361de394512a29682f9cb2d2846", campaign_id: "102"}

但我从我的 javascript 控制台收到此错误:

XMLHttpRequest cannot load http://localhost:5000/api/ia/v1/user_likes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://s3.amazonaws.com' is therefore not allowed access. The response had HTTP status code 500.

我发现在构建 Node 应用程序时这是一个 cors 错误。我运行 jQuery AJAX 请求的页面是 http。以下是我认为我配置不正确的 Python 代码部分:

from flask import Flask, request, redirect
from flask.ext.cors import CORS, cross_origin

app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'application/json'

还有路线:

@app.route("/api/ia/v1/user_likes", methods=['POST', 'OPTIONS'])
def user_likes():
    validate = validate_request(request.data)

    return 'something'

我的 Python 错误也返回了一个错误,因为请求永远不会到达这行代码:

def validate_request(object_from_user):
    load_object = json.loads(object_from_user)

我可以稍后解决。无论如何,有人对 Python 的 Cors 配置有什么建议吗?

【问题讨论】:

    标签: javascript jquery python ajax flask


    【解决方案1】:

    在我尝试了其他人的建议和答案之后。这是我使用的,它有效。

    步骤:

    1. pip install flask flask-cors

    2. 复制并粘贴到app.py文件中

    代码

    from flask import Flask, jsonify
    from flask_cors import CORS, cross_origin
    
    app = Flask(__name__)
    CORS(app, support_credentials=True)
    
    @app.route("/login")
    @cross_origin(supports_credentials=True)
    def login():
      return jsonify({'success': 'ok'})
    
    if __name__ == "__main__":
      app.run(host='0.0.0.0', port=8000, debug=True)
    
    1. python app.py

    注意:请确保在您客户端的 ajax 配置中有以下内容:

    $.ajaxSetup({
        type: "POST",
        data: {},
        dataType: 'json',
        xhrFields: {
           withCredentials: true
        },
        crossDomain: true,
        contentType: 'application/json; charset=utf-8'
    });
    

    如果有人想知道,support_credentials=True 只是意味着它沿着有效负载来回发送 cookie。

    【讨论】:

    • 就我而言,ajax 设置添加了额外的标头字段,例如标头:{ 'Access-Control-Allow-Origin':'*' },
    【解决方案2】:

    Flask 有flask-cors 模块。 下面是sn-p的代码和过程。

    1. pip install -U flask-cors

    2. 在您的烧瓶应用程序中添加以下行:

      from flask import Flask
      from flask_cors import CORS, cross_origin
      
      app = Flask(__name__)
      CORS(app)
      
      @app.route("/")
      def helloWorld():
          return "Hello world"
      

    点击this link查看更多内容

    【讨论】:

    • 这是 Flask 的最新更新吗?我有一段时间没有写 Python 了。
    • 对我来说,这适用于 GET 和 POST 路由,但是当我添加 DELETE 路由时,由于 CORS 原因它失败了...?
    【解决方案3】:

    这里是如何通过自己处理 CORS 细节来弄脏你的手:

    handle_result = {'result': True, 'msg': 'success'}
    
    try:
        # origin, where does this request come from, like www.amazon.com
        origin = flask.request.environ['HTTP_ORIGIN']
    except KeyError:
        origin = None
    
    # only accept CORS request from amazon.com
    if origin and origin.find('.amazon.com') > -1:
        resp = flask.make_response(str(handle_result))
        resp.headers['Content-Type'] = 'application/json'
    
        h = resp.headers
        # prepare headers for CORS authentication
        h['Access-Control-Allow-Origin'] = origin
        h['Access-Control-Allow-Methods'] = 'GET'
        h['Access-Control-Allow-Headers'] = 'X-Requested-With'
    
        resp.headers = h
        return resp
    
    return flask.abort(403)
    

    【讨论】:

      【解决方案4】:

      请在你的 python 文件中使用@cross_origin(origin='*')

      from flask import Flask, jsonify
      from flask_cors import CORS, cross_origin
      
      app = Flask(__name__)
      
      @app.route("/login", methods = ['GET'])
      @cross_origin(origin='*')
      def login():
        return jsonify({'success': 'ok'})
      
      if __name__ == "__main__":
        app.run(host='0.0.0.0', port=8000, debug=True)
      

      【讨论】:

        【解决方案5】:

        在路由装饰器之后使用 cors 装饰器。

        这是文档中的一个 sn-p...

        @app.route("/")
        @cross_origin() # allow all origins all methods.
        def helloWorld():
          return "Hello, cross-origin-world!"
        

        现在,您似乎正在使用 json,如果是这种情况,您可能应该只阅读文档,因为它特别提到了这个用例,以及要设置的 cors_headers... 它在首屏,但是这个文档很好书面且易于理解。

        http://flask-cors.readthedocs.org/en/latest/#using-json-with-cors

        【讨论】:

        • 我今天早些时候看了这些文档并尝试了几种不同的配置。添加@cross_origin 对我当前的配置没有帮助。
        • 在 JSON 的情况下,以前您需要指定允许的标头。现在这很放松,应该可以开箱即用。如果您有任何问题,请告诉我。
        • 我也在尝试实现这一点。我使用了@cors 装饰器,仍然得到
        • 这也适用于蓝图吗?
        【解决方案6】:

        我尝试了上述所有解决方案,但他们一直对我失败。 我敢肯定,大多数解决方案都会奏效,但我在客户端应用程序中犯了一个非常明显的错误。也许这可以为你们中的一些人节省一些调试时间。 我的请求,我通过

        调用了我的 REST 服务
        'localhost:<port>/<myApi>'
        

        对我来说,解决方法很简单,只需将服务调用为 http...:

        'http://localhost:<port>/<myApi>'
        

        一个愚蠢的错误。

        【讨论】:

        • 我犯了同样的错误。似乎 axios 不假设 http(s)。
        【解决方案7】:

        试试这个:

        @app.after_request
        def add_headers(response):
            response.headers.add('Access-Control-Allow-Origin', '*')
            response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
        

        我在 Flask 网站上尝试过 @cross_origin 教程,但是它对我不起作用。

        但您似乎可以稍后在回复中添加标题。

        这是我认为可能有用的剩余代码。

        from flask import Flask, request
        from sklearn.externals import joblib
        
        app = Flask(__name__)
        

        【讨论】:

          【解决方案8】:

          以下解决方案对我有用。 我包含了一个方法,它将添加您所需的标头,然后引发 HTTP 响应。 例如:

          def some_method(response_data, status_code):
              response_data = //here you can manipulate the data, JSONify, convert arrays into objects or vice versa
              headers = {
                  "Content-Type": "application/json",
                  "Access-Control-Allow-Origin": '*',
                  "Access-Control-Allow-Methods": 'PUT, GET, POST, DELETE, OPTIONS',
                  "Access-Control-Allow-Headers": 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
                  }
              //THEN RAISE HTTPResponse
              raise HTTPResponse(status, headers, body)
          

          注意:上面的方法不是python编译的,所以你可能需要编辑它。

          【讨论】:

            【解决方案9】:

            基于 GyuHyeon Choi 的回复,但添加了 return response 和额外的 Access-Control-Expose-Headers 对我有用。

            @app.after_request
            def add_headers(response):
                response.headers.add('Content-Type', 'application/json')
                response.headers.add('Access-Control-Allow-Origin', '*')
                response.headers.add('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS')
                response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
                response.headers.add('Access-Control-Expose-Headers', 'Content-Type,Content-Length,Authorization,X-Pagination')
                return response
            

            【讨论】:

              【解决方案10】:

              在客户端,您只需要确保您的服务器正在处理的数据类型。 例如表单数据或json。

              注意:cross_origin 的位置要正确。

              对我来说,下面写的代码很神奇

              from flask import Flask,request,jsonify
              from flask_cors import CORS,cross_origin
              app=Flask(__name__)
              CORS(app, support_credentials=True)
              @app.route('/api/test', methods=['POST', 'GET','OPTIONS'])
              @cross_origin(supports_credentials=True)
              def index():
                  if(request.method=='POST'):
                   some_json=request.get_json()
                   return jsonify({"key":some_json})
                  else:
                      return jsonify({"GET":"GET"})
              
              
              if __name__=="__main__":
                  app.run(host='0.0.0.0', port=5000)
              

              【讨论】:

                【解决方案11】:

                我已经使用以下命令安装了烧瓶,并使用如下声明:

                pips3.6 install --user flask-cors

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

                【讨论】:

                  猜你喜欢
                  • 2021-10-11
                  • 1970-01-01
                  • 2020-11-28
                  • 2023-03-28
                  • 2021-04-06
                  • 2019-07-26
                  • 2019-06-04
                  • 2018-07-20
                  • 2021-05-06
                  相关资源
                  最近更新 更多