ফ্লাস্কে সিওআরএস কীভাবে সক্ষম করবেন


92

আমি jquery ব্যবহার করে ক্রস অরিজিনের অনুরোধ করার চেষ্টা করছি তবে বার্তাটি দিয়ে এটি প্রত্যাখ্যান করে চলেছে

এক্সএমএলএইচটিপিআরকোয়েস্টটি http: // লোড করতে পারে না ... অনুরোধকৃত উত্সটিতে কোনও 'অ্যাক্সেস-কন্ট্রোল-মঞ্জুরি-উত্স' নেই present উত্স ... সুতরাং অ্যাক্সেস অনুমোদিত নয়।

আমি ফ্লাস্ক, হিরকু এবং জ্যাকারি ব্যবহার করছি

ক্লায়েন্ট কোডটি দেখতে এরকম দেখাচ্ছে:

$(document).ready(function() {
    $('#submit_contact').click(function(e){
        e.preventDefault();
        $.ajax({
            type: 'POST',
            url: 'http://...',
            // data: [
            //      { name: "name", value: $('name').val()},
            //      { name: "email", value: $('email').val() },
            //      { name: "phone", value: $('phone').val()},
            //      { name: "description", value: $('desc').val()}
            //
            // ],
            data:"name=3&email=3&phone=3&description=3",
            crossDomain:true,
            success: function(msg) {
                alert(msg);
            }
        });
    }); 
});

হিরকু দিকে আমি ফ্লাস্ক ব্যবহার করছি এবং এটি এর মতো

from flask import Flask,request
from flask.ext.mandrill import Mandrill
try:
    from flask.ext.cors import CORS  # The typical way to import flask-cors
except ImportError:
    # Path hack allows examples to be run without installation.
    import os
    parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    os.sys.path.insert(0, parentdir)

    from flask.ext.cors import CORS
app = Flask(__name__)

app.config['MANDRILL_API_KEY'] = '...'
app.config['MANDRILL_DEFAULT_FROM']= '...'
app.config['QOLD_SUPPORT_EMAIL']='...'
app.config['CORS_HEADERS'] = 'Content-Type'

mandrill = Mandrill(app)
cors = CORS(app)

@app.route('/email/',methods=['POST'])
def hello_world():
    name=request.form['name']
    email=request.form['email']
    phone=request.form['phone']
    description=request.form['description']

    mandrill.send_email(
        from_email=email,
        from_name=name,
        to=[{'email': app.config['QOLD_SUPPORT_EMAIL']}],
        text="Phone="+phone+"\n\n"+description
    )

    return '200 OK'

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

উত্তর:


174

আমি হিরোকুতে মোতায়েন করার সময় আমার জন্য যা কাজ করেছিল তা এখানে।

http://flask-cors.readthedocs.org/en/latest/
চালিয়ে ফ্লাস্ক- কোর ইনস্টল করুন - pip install -U flask-cors

from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

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

37
প্লাস 1 হ্যালো ক্রস অরিজিন ওয়ার্ল্ডের জন্য!
সাইমন নিকোলস

এটি আমার জন্য একমাত্র সমাধান যা কাজ করে। ধন্যবাদ!
psc37

4
তুমি জীবন রক্ষাকারী! কবজির মতো কাজ করেছেন।
রোহিত স্বামী

ওহে! আমার ক্ষেত্রে কী ঘটেছিল তা বুঝতে আপনি আমাকে সাহায্য করতে পারেন? আমি পাইথন / ফ্লাস্ক ব্যবহার করে একটি সাধারণ এপিআই লিখেছি, এটির জন্য একটি দর্শন ছাড়াই। আমি curlকমান্ড দ্বারা এটি পৌঁছেছি । এখন আমি একটি সংক্ষিপ্ত এইচটিএমএল পৃষ্ঠা লিখেছি এবং আমার এপিআইতে জেএস আনার () পদ্ধতির সাহায্যে একটি অনুরোধ করার চেষ্টা করছিলাম যা হেরোকুর উপর ভিত্তি করে এবং আমার সিওআরএস ত্রুটি রয়েছে। আমি আপনার কোড প্রয়োগ করার পরে, আমার টার্মিনালটি জেএসএনের পরিবর্তে এইচটিএমএল কোড (HTTP / 1.1 503 পরিষেবা অনুপলব্ধ) দিয়ে আমাকে প্রতিক্রিয়া জানাতে শুরু করেছে। এখানে ত্রুটি কি হতে পারে? ধন্যবাদ!!
নিকিতা বাশারকিন

4
যে কেউ কপি তাদের আবেদন এই কোডটি করার আগে, দয়া ডকুমেন্টেশন খুঁজে বার করো কারণ শুধুমাত্র কিছু এই লাইন প্রয়োজন হয়।
রোভিকো

46

ঠিক আছে, আমি মনে করি না যে গালুসকাক দ্বারা উল্লিখিত সরকারী স্নিপেটটি সর্বত্র ব্যবহার করা উচিত, আমাদের কেসটি উদ্বেগ করা উচিত যে হ্যান্ডলারের সময় যেমন hello_worldফাংশন চলাকালীন কিছু বাগ শুরু হতে পারে । প্রতিক্রিয়াটি সঠিক বা অযৌক্তিক হোক না কেন, শিরোনামটি Access-Control-Allow-Originআমাদের উদ্বেগ করা উচিত should সুতরাং, জিনিসটি খুব সহজ, যেমন নমোর মতো:

@blueprint.after_request # blueprint can also be app~~
def after_request(response):
    header = response.headers
    header['Access-Control-Allow-Origin'] = '*'
    return response

এটাই সব ~~


এটি প্রাথমিক সিআরইউডি অপারেশন সহ একটি ছোট প্রকল্পের জন্যও আমাকে সহায়তা করেছিল। অভিনব কিছু লাগবে না, কেবল ত্রুটিটি বাইপাস করুন :)
নর্শে

34

আমি কেবল একই সমস্যার মুখোমুখি হয়েছি এবং আমি বিশ্বাস করে এসেছি যে অন্যান্য উত্তরগুলি হওয়া দরকারের তুলনায় কিছুটা জটিল, সুতরাং যারা আরও বেশি গ্রন্থাগার বা সাজসজ্জার উপর নির্ভর করতে চান না তাদের জন্য আমার এই পদ্ধতিটি এখানে:

একটি CORS অনুরোধ আসলে দুটি HTTP অনুরোধ নিয়ে গঠিত। একটি প্রিফলাইট অনুরোধ এবং তারপরে একটি প্রকৃত অনুরোধ যা কেবল তখনই তৈরি করা হয় যদি প্রিফলাইট সফলভাবে পাস হয়।

প্রিফলাইট অনুরোধ

প্রকৃত ক্রস ডোমেন POSTঅনুরোধের আগে , ব্রাউজার একটি OPTIONSঅনুরোধ জারি করবে । এই প্রতিক্রিয়াটি কোনও দেহ ফেরত দেওয়া উচিত নয়, তবে কেবলমাত্র কিছু আশ্বাসযুক্ত শিরোলেখ ব্রাউজারকে বলছে যে এই ক্রস-ডোমেন অনুরোধটি করা ঠিক আছে এবং এটি কোনও ক্রস সাইট স্ক্রিপ্টিং আক্রমণের অংশ নয়।

মডিউল make_responseথেকে ফাংশনটি ব্যবহার করে এই প্রতিক্রিয়াটি তৈরি করতে আমি পাইথন ফাংশন লিখেছিলাম flask

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add("Access-Control-Allow-Headers", "*")
    response.headers.add("Access-Control-Allow-Methods", "*")
    return response

এই প্রতিক্রিয়াটি একটি ওয়াইল্ডকার্ড যা সমস্ত অনুরোধের জন্য কাজ করে। আপনি যদি সিওআরএস দ্বারা প্রাপ্ত অতিরিক্ত সুরক্ষা চান তবে আপনাকে উত্স, শিরোনাম এবং পদ্ধতিগুলির একটি শ্বেত তালিকা সরবরাহ করতে হবে।

এই প্রতিক্রিয়াটি আপনার (ক্রোম) ব্রাউজারকে এগিয়ে যেতে এবং আসল অনুরোধটি করতে রাজি করবে।

আসল অনুরোধ

প্রকৃত অনুরোধটি পরিবেশন করার সময় আপনাকে একটি সিওআরএস শিরোনাম যুক্ত করতে হবে - অন্যথায় ব্রাউজারটি আমন্ত্রণকারী জাভাস্ক্রিপ্ট কোডটিতে প্রতিক্রিয়া ফিরিয়ে দেবে না। পরিবর্তে অনুরোধ ক্লায়েন্ট পক্ষ থেকে ব্যর্থ হবে। Jsonify সহ উদাহরণ

response = jsonify({"order_id": 123, "status": "shipped"}
response.headers.add("Access-Control-Allow-Origin", "*")
return response

আমি তার জন্য একটি ফাংশনও লিখেছি।

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response

আপনাকে ওয়ান-লাইনার ফেরত দেওয়ার অনুমতি দেয়।

চূড়ান্ত কোড

from flask import Flask, request, jsonify, make_response
from models import OrderModel

flask_app = Flask(__name__)

@flask_app.route("/api/orders", methods=["POST", "OPTIONS"])
def api_create_order():
    if request.method == "OPTIONS": # CORS preflight
        return _build_cors_prelight_response()
    elif request.method == "POST": # The actual request following the preflight
        order = OrderModel.create(...) # Whatever.
        return _corsify_actual_response(jsonify(order.to_dict()))
    else
        raise RuntimeError("Weird - don't know how to handle method {}".format(request.method))

def _build_cors_prelight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add('Access-Control-Allow-Headers', "*")
    response.headers.add('Access-Control-Allow-Methods', "*")
    return response

def _corsify_actual_response(response):
    response.headers.add("Access-Control-Allow-Origin", "*")
    return response

অনেক ধন্যবাদ @ নিলস বি।, আপনি আমার সময় বাঁচালেন। আমি এর আগে কর্স কনফিগারেশন যুক্ত করেছি তবে এটি সঠিকভাবে সেট আপ করা হয়নি।
Günay Gültekin

4
এটি ফ্লাস্কের এই করস ইস্যুতে এখন পর্যন্ত সেরা উত্তর। মোহন মত কাজ! ধন্যবাদ @ নীলস
চন্দ্র কণ্ঠ

আপনার খুব বিস্তারিত ব্যাখ্যার জন্য ধন্যবাদ !! এটি খুব সহায়ক ছিল!
jones-chris

সিওআরএস এবং আপনার সহ অনেকগুলি সমাধান ব্যবহার করুন তবে এগুলি সবই আউজের পক্ষে কাজ করে না (এই উদাহরণটি অনুসরণ করুন - aws.amazon.com/getting-st সূত্র / প্রকল্পগুলি / কি), কেউ কি জানেন কী চলছে?
স্টিরিওম্যাচিং

এই সমাধানটি সত্যই সহজ তবে মার্জিত! ধন্যবাদ, আপনি সত্যই আমার সময় বাঁচিয়েছেন।
গেরি

22

আপনি সব রুটের জন্য CORS সক্ষম করতে চান, তাহলে শুধু ইনস্টল flask_cors এক্সটেনশন ( pip3 install -U flask_cors) এবং মোড়ানো appভালো: CORS(app)

এটি করার জন্য এটি যথেষ্ট (আমি POSTএকটি চিত্র আপলোড করার অনুরোধের সাথে এটি পরীক্ষা করেছি এবং এটি আমার পক্ষে কাজ করেছে):

from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # This will enable CORS for all routes

গুরুত্বপূর্ণ দ্রষ্টব্য: যদি আপনার রুটে কোনও ত্রুটি রয়েছে, তবে আমাদের বলুন যে আপনি কোনও ভেরিয়েবল প্রিন্ট করার চেষ্টা করছেন যা বিদ্যমান নেই, আপনি একটি কর্ড ত্রুটি সম্পর্কিত বার্তা পাবেন যা বাস্তবে সিওআরএসের সাথে কোনও সম্পর্ক নেই।


4
অনেক ধন্যবাদ! এই সাধারণ এবং সাধারণ সমাধানটি আমাকে আর করস ব্লক ছাড়াই আমার প্রতিক্রিয়া ওয়েব কোড থেকে আমার এপিআই কল করার অনুমতি দেয়।
সেবাস্তিয়ান ডিয়াজ

4
ধন্যবাদ ! গুরুত্বপূর্ণ নোট অংশটি আমাকে অনেক সময় বাঁচিয়েছিল।
গ্যাব্রিয়েল

4

নিম্নলিখিত সজ্জা চেষ্টা করুন:

@app.route('/email/',methods=['POST', 'OPTIONS']) #Added 'Options'
@crossdomain(origin='*')                          #Added
def hello_world():
    name=request.form['name']
    email=request.form['email']
    phone=request.form['phone']
    description=request.form['description']

    mandrill.send_email(
        from_email=email,
        from_name=name,
        to=[{'email': app.config['QOLD_SUPPORT_EMAIL']}],
        text="Phone="+phone+"\n\n"+description
    )

    return '200 OK'

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

এই সাজসজ্জাটি নিম্নলিখিত হিসাবে তৈরি করা হবে:

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

আপনি এই প্যাকেজটি ফ্লাস্ক-সিওআরএসও পরীক্ষা করে দেখতে পারেন


এখনও কাজ করছে না. আমি ইতিমধ্যে এটি চেষ্টা করেছি এবং আমি ফ্লাস্ক-সিওআরএস প্যাকেজটিও ব্যবহার করেছি। আমার মনে হয় ফ্লাস্ক-সিওআরএস এর উপরে নির্মিত হয়েছে
লোপস

3

এখানে বর্ণিত সমাধানটির উন্নতি হচ্ছে: https://stackoverflow.com/a/52875875/10299604

সঙ্গে after_requestআমরা সব ব্যবস্থা করতে সক্ষম CORS প্রতিক্রিয়া হেডার আমাদের এন্ড পয়েন্ট অতিরিক্ত কোড যোগ করতে এড়ানো:

    ### CORS section
    @app.after_request
    def after_request_func(response):
        origin = request.headers.get('Origin')
        if request.method == 'OPTIONS':
            response = make_response()
            response.headers.add('Access-Control-Allow-Credentials', 'true')
            response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
            response.headers.add('Access-Control-Allow-Headers', 'x-csrf-token')
            response.headers.add('Access-Control-Allow-Methods',
                                'GET, POST, OPTIONS, PUT, PATCH, DELETE')
            if origin:
                response.headers.add('Access-Control-Allow-Origin', origin)
        else:
            response.headers.add('Access-Control-Allow-Credentials', 'true')
            if origin:
                response.headers.add('Access-Control-Allow-Origin', origin)

        return response
    ### end CORS section

2

আমার সমাধানটি app.route এর চারপাশে একটি মোড়ক:

def corsapp_route(path, origin=('127.0.0.1',), **options):
    """
    Flask app alias with cors
    :return:
    """

    def inner(func):
        def wrapper(*args, **kwargs):
            if request.method == 'OPTIONS':
                response = make_response()
                response.headers.add("Access-Control-Allow-Origin", ', '.join(origin))
                response.headers.add('Access-Control-Allow-Headers', ', '.join(origin))
                response.headers.add('Access-Control-Allow-Methods', ', '.join(origin))
                return response
            else:
                result = func(*args, **kwargs)
            if 'Access-Control-Allow-Origin' not in result.headers:
                result.headers.add("Access-Control-Allow-Origin", ', '.join(origin))
            return result

        wrapper.__name__ = func.__name__

        if 'methods' in options:
            if 'OPTIONS' in options['methods']:
                return app.route(path, **options)(wrapper)
            else:
                options['methods'].append('OPTIONS')
                return app.route(path, **options)(wrapper)

        return wrapper

    return inner

@corsapp_route('/', methods=['POST'], origin=['*'])
def hello_world():
    ...

2

উপরের সমস্ত প্রতিক্রিয়া ঠিকঠাক কাজ করে তবে আপনি সম্ভবত একটি সিওআরএস ত্রুটি পেয়ে যাবেন, যদি অ্যাপ্লিকেশনটি কোনও কী-ত্রুটির মতো আপনি পরিচালনা করছেন না এমন একটি ত্রুটি ছুড়ে দেয়, উদাহরণস্বরূপ if আপনি ব্যতিক্রমগুলির সমস্ত দৃষ্টান্তগুলি খুঁজে পেতে এবং সার্ভারের প্রতিক্রিয়ায় CORS প্রতিক্রিয়া শিরোনাম যুক্ত করতে একটি ত্রুটি হ্যান্ডলার যুক্ত করতে পারেন

সুতরাং একটি ত্রুটি হ্যান্ডলার সংজ্ঞায়িত করুন - ত্রুটি.পি:

from flask import json, make_response, jsonify
from werkzeug.exceptions import HTTPException

# define an error handling function
def init_handler(app):

    # catch every type of exception
    @app.errorhandler(Exception)
    def handle_exception(e):

        #loggit()!          

        # return json response of error
        if isinstance(e, HTTPException):
            response = e.get_response()
            # replace the body with JSON
            response.data = json.dumps({
                "code": e.code,
                "name": e.name,
                "description": e.description,
            })
        else:
            # build response
            response = make_response(jsonify({"message": 'Something went wrong'}), 500)

        # add the CORS header
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.content_type = "application/json"
        return response

তারপরে বিল্লালের উত্তরটি ব্যবহার করুন :

from flask import Flask
from flask_cors import CORS

# import error handling file from where you have defined it
from . import errors

app = Flask(__name__)
CORS(app) # This will enable CORS for all routes
errors.init_handler(app) # initialise error handling 

2

আমি ফ্ল্যাস্ক ব্যবহার করে এবং এই লাইব্রেরির সাথে অজগরটিতে একই সমস্যাটি সমাধান করেছি। flask_cors

তথ্যসূত্র: https://flask-cors.readthedocs.io/en/latest/


যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত উত্তর পরিবর্তিত হলে লিঙ্কযুক্ত উত্তরগুলি অবৈধ হতে পারে। - পর্যালোচনা থেকে
জেসন অ্যালার

0

যদি আপনি নিজের সমস্যাটি খুঁজে না পান এবং আপনার কোডটি কাজ করা উচিত তবে এটি হতে পারে আপনার অনুরোধটি সর্বাধিক সময়ের মধ্যে পৌঁছেছে হিরকু আপনাকে একটি অনুরোধ করার অনুমতি দেয়। 30 সেকেন্ডের বেশি সময় লাগলে হেরোকু অনুরোধগুলি বাতিল করে।

তথ্যসূত্র: https://devcenter.heroku.com/articles/request-timeout

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.