मैं फ्लास्क में प्रतिक्रिया हेडर कैसे सेट करूं?


99

यह मेरा कोड है:

@app.route('/hello', methods=["POST"])
def hello():
    resp = make_response()
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp

हालाँकि, जब मैं ब्राउज़र से अपने सर्वर से अनुरोध करता हूँ तो मुझे यह त्रुटि मिलती है:

XMLHttpRequest cannot load http://localhost:5000/hello. 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

मैंने भी इस अनुरोध को "अनुरोध" के बाद "प्रतिक्रिया हेडर" स्थापित करने की कोशिश की है:

@app.after_request
def add_header(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    return response

कोई पाँसा नहीं। मुझे समान त्रुटि मिली। वहाँ सिर्फ मार्ग समारोह में प्रतिक्रिया हेडर सेट करने के लिए एक रास्ता है? ऐसा कुछ आदर्श होगा:

@app.route('/hello', methods=["POST"])
    def hello(response): # is this a thing??
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response

लेकिन मैं ऐसा करने के लिए वैसे भी नहीं मिल सकता। कृपया मदद कीजिए।

संपादित करें

अगर मैं url को POST अनुरोध के साथ कर्ल करता हूँ तो:

curl -iX POST http://localhost:5000/hello

मुझे यह प्रतिक्रिया मिल रही है:

HTTP/1.0 500 INTERNAL SERVER ERROR
Content-Type: text/html
Content-Length: 291
Server: Werkzeug/0.9.6 Python/2.7.6
Date: Tue, 16 Sep 2014 03:58:42 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.</p>

कोई विचार?

जवाबों:


96

आप इसे बहुत आसानी से कर सकते हैं:

@app.route("/")
def home():
    resp = flask.Response("Foo bar baz")
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp

फ्लास्क को देखें। रिस्पॉन्स और फ्लास्क.make_response ()

लेकिन कुछ मुझे बताता है कि आपको एक और समस्या है, क्योंकि after_requestइसे सही ढंग से संभालना चाहिए था।

संपादित करें
मैंने अभी देखा कि आप पहले से ही इसका उपयोग कर रहे हैं make_responseजो इसे करने के तरीकों में से एक है। जैसा मैंने पहले कहा था, after_requestवैसे ही काम करना चाहिए था। समापन बिंदु को कर्ल के माध्यम से मारने की कोशिश करें और देखें कि हेडर क्या हैं:

curl -i http://127.0.0.1:5000/your/endpoint

तुम्हे देखना चाहिए

> curl -i 'http://127.0.0.1:5000/'
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 11
Access-Control-Allow-Origin: *
Server: Werkzeug/0.8.3 Python/2.7.5
Date: Tue, 16 Sep 2014 03:47:13 GMT

पहुँच-नियंत्रण-अनुमति-मूल शीर्ष लेख।

संपादित करें 2
जैसा कि मुझे संदेह था, आपको 500 मिल रहे हैं इसलिए आप हेडर सेट नहीं कर रहे हैं जैसा आपने सोचा था। app.debug = Trueएप्लिकेशन शुरू करने से पहले जोड़ने का प्रयास करें और फिर से प्रयास करें। आपको समस्या का मूल कारण बताते हुए कुछ आउटपुट प्राप्त करने चाहिए।

उदाहरण के लिए:

@app.route("/")
def home():
    resp = flask.Response("Foo bar baz")
    user.weapon = boomerang
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp

इसके साथ एक नीच स्वरूपित html त्रुटि पृष्ठ देता है, नीचे में (कर्ल कमांड के लिए उपयोगी)

Traceback (most recent call last):
...
  File "/private/tmp/min.py", line 8, in home
    user.weapon = boomerang
NameError: global name 'boomerang' is not defined

24

make_responseफ्लास्क का उपयोग कुछ इस तरह से

@app.route("/")
def home():
    resp = make_response("hello") #here you could use make_response(render_template(...)) too
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp

से कुप्पी डॉक्स ,

flask.make_response (* args)

कभी-कभी एक दृश्य में अतिरिक्त हेडर सेट करना आवश्यक होता है। क्योंकि विचारों को प्रतिक्रिया वस्तुओं को वापस करने की ज़रूरत नहीं है, लेकिन एक मान वापस कर सकते हैं जो कि फ्लास्क द्वारा एक प्रतिक्रिया वस्तु में परिवर्तित हो जाता है, यह हेडर को जोड़ने के लिए मुश्किल हो जाता है। इस फ़ंक्शन को रिटर्न का उपयोग करने के बजाय कहा जा सकता है और आपको एक प्रतिक्रिया वस्तु मिलेगी जिसे आप हेडर संलग्न करने के लिए उपयोग कर सकते हैं।



5

यह काम मेरे लिए

from flask import Flask
from flask import Response

app = Flask(__name__)

@app.route("/")
def home():
    return Response(headers={'Access-Control-Allow-Origin':'*'})

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

2
वहाँ भी संकेतन है return Response(headers={'Access-Control-Allow-Origin':'*'})जो मुझे साफ दिखता है।
हरमन

4

यह मेरे फ्लास्क एप्लिकेशन में मेरे हेडर को कैसे जोड़ा गया और इसने पूरी तरह से काम किया

@app.after_request
def add_header(response):
    response.headers['X-Content-Type-Options'] = 'nosniff'
    return response

0

हम फ्लास्क एप्लिकेशन संदर्भ का उपयोग करके पायथन फ्लास्क एप्लिकेशन में प्रतिक्रिया हेडर सेट कर सकते हैं flask.g

फ्लास्क एप्लिकेशन के संदर्भ में प्रतिक्रिया हेडर सेट करने का यह तरीका flask.gथ्रेड सुरक्षित है और इसे एप्लिकेशन की किसी भी फ़ाइल से कस्टम और डायनामिक विशेषताओं को सेट करने के लिए उपयोग किया जा सकता है, यह विशेष रूप से सहायक है यदि हम किसी भी सहायक वर्ग से कस्टम / डायनामिक प्रतिक्रिया हेडर सेट कर रहे हैं, किसी अन्य फ़ाइल से भी एक्सेस किया जा सकता है (जैसे कि मिडलवेयर आदि), यह flask.gकेवल उस थ्रेड के लिए वैश्विक और मान्य है।

यदि मैं इस एप से कॉल की जा रही किसी अन्य एपीआई / http कॉल से प्रतिक्रिया हेडर पढ़ना चाहता हूं, और फिर इस ऐप के लिए किसी भी प्रतिक्रिया हेडर के रूप में सेट करें।

नमूना कोड: फ़ाइल: helper.py

import flask
from flask import request, g
from multidict import CIMultiDict
from asyncio import TimeoutError as HttpTimeout
from aiohttp import ClientSession

    def _extract_response_header(response)
      """
      extracts response headers from response object 
      and stores that required response header in flask.g app context
      """
      headers = CIMultiDict(response.headers)
      if 'my_response_header' not in g:
        g.my_response_header= {}
        g.my_response_header['x-custom-header'] = headers['x-custom-header']


    async def call_post_api(post_body):
      """
      sample method to make post api call using aiohttp clientsession
      """
      try:
        async with ClientSession() as session:
          async with session.post(uri, headers=_headers, json=post_body) as response:
            responseResult = await response.read()
            _extract_headers(response, responseResult)
            response_text = await response.text()
      except (HttpTimeout, ConnectionError) as ex:
        raise HttpTimeout(exception_message)

फ़ाइल: middleware.py

import flask
from flask import request, g

class SimpleMiddleWare(object):
    """
    Simple WSGI middleware
    """

    def __init__(self, app):
        self.app = app
        self._header_name = "any_request_header"

    def __call__(self, environ, start_response):
        """
        middleware to capture request header from incoming http request
        """
        request_id_header = environ.get(self._header_name)
        environ[self._header_name] = request_id_header

        def new_start_response(status, response_headers, exc_info=None):
            """
            set custom response headers
            """
            # set the request header as response header
            response_headers.append((self._header_name, request_id_header))
            # this is trying to access flask.g values set in helper class & set that as response header
            values = g.get(my_response_header, {})
            if values.get('x-custom-header'):
                response_headers.append(('x-custom-header', values.get('x-custom-header')))
            return start_response(status, response_headers, exc_info)

        return self.app(environ, new_start_response)

मेन क्लास से मिडलवेयर को कॉल करना

फ़ाइल: main.py

from flask import Flask
import asyncio
from gevent.pywsgi import WSGIServer
from middleware import SimpleMiddleWare

    app = Flask(__name__)
    app.wsgi_app = SimpleMiddleWare(app.wsgi_app)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.