جافاسكريبت - حل مشكلة مشاركة الموارد عبر الأصول مع فلاسک


لطلب ajax التالي من نوع post لـ Flask (كيف يمكنني استخدام البيانات المرسلة من ajax في flask؟):

$.ajax({
    url: "http://127.0.0.1:5000/foo", 
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify({'inputVar': 1}),
    success: function( data ) { 
        alert( "success" + data );
    }   
});

أتلقى خطأ مشاركة الموارد عبر المصادر (CORS):

No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'null' is therefore not allowed access. 
The response had HTTP status code 500.

حاولت حله بالطرقتين التاليتين، لكن لا يبدو أن أيًا منهما يعمل.

  1. استخدام Flask-CORS

هذه إضافة Flask للتعامل مع CORS والتي يجب أن تجعل AJAX عبر المصادر ممكنًا.

  • http://flask-cors.readthedocs.org/en/latest/
  • كيفية تمكين CORS في فلاسک و هيروكو
  • ملف Flask-cors الغلاف لا يعمل عند تطبيق غلاف مصادقة jwt.
  • جافاسكريبت - لا يوجد رأس 'Access-Control-Allow-Origin' على المورد المطلوب

خادمي pythonServer.py يستخدم هذا الحل:

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

app = Flask(__name__)
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'

@app.route('/foo', methods=['POST','OPTIONS'])
@cross_origin(origin='*',headers=['Content-Type','Authorization'])
def foo():
    return request.json['inputVar']

if __name__ == '__main__':
    app.run()
  1. استخدام مزخرف فلاسكي محدد

هذه قطعة رمز رسمية من Flask تحدد مُزيَّنًا يجب أن يسمح بـ CORS على الدوال التي يزيّنها.

  • http://flask.pocoo.org/snippets/56/
  • بايثون فلاسـك طلب HTTP POST عبر المواقع - لا يعمل لأصول معينة مسموح بها
  • http://chopapp.com/#351l7gc3

خادمي pythonServer.py يستخدم هذا الحل:

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

app = Flask(__name__)

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

@app.route('/foo', methods=['GET','POST','OPTIONS'])
@crossdomain(origin="*")
def foo():
    return request.json['inputVar']

if __name__ == '__main__':
    app.run()

هل يمكنك أن تعطينا بعض المؤشرات عن سبب ذلك؟

الإجابة رقم 1

يمكنك الحصول على النتائج ببساطة:

@app.route('your route', methods=['GET'])
def yourMethod(params):
    response = flask.jsonify({'some': 'data'})
    response.headers.add('Access-Control-Allow-Origin', '*')
    return response

الإجابة رقم 2

حسنًا، واجهت نفس المشكلة. بالنسبة للمستخدمين الجدد الذين قد يصلون إلى هذه الصفحة، فقط اتبعوا الوثائق الرسمية الخاصة بهم.

ثبت flask-cors

pip install -U flask-cors

ثم بعد تهيئة التطبيق، قم بتهيئة flask-cors باستخدام المعاملات الافتراضية:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
   return "Hello, cross-origin-world!"

الإجابة رقم 3

لقد نجح بشكل ممتاز، بعد تعديل بعض البتات في كودك

initialization
app = Flask(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy   dog'
app.config['CORS_HEADERS'] = 'Content-Type'

cors = CORS(app, resources={r"/foo": {"origins": "http://localhost:port"}})

@app.route('/foo', methods=['POST'])
@cross_origin(origin='localhost',headers=['Content- Type','Authorization'])
def foo():
    return request.json['inputVar']

if __name__ == '__main__':
   app.run()

لقد استبدلت * بـ localhost. حيث أنه حسب ما قرأت في العديد من المدونات والمشاركات، يجب أن تسمح بالوصول لنطاق محدد