Python 如何在烧瓶中设置响应标题?
这是我的代码:Python 如何在烧瓶中设置响应标题?,python,flask,Python,Flask,这是我的代码: @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 'Acc
@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
没有骰子。我也犯了同样的错误。有没有办法只在route函数中设置响应头?像这样的东西很理想:
@app.route('/hello', methods=["POST"])
def hello(response): # is this a thing??
response.headers['Access-Control-Allow-Origin'] = '*'
return response
但是我找不到任何方法来做这件事。请帮忙
编辑
如果我使用POST请求卷曲url,如下所示:
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>
HTTP/1.0 500内部服务器错误
内容类型:text/html
内容长度:291
服务器:Werkzeug/0.9.6 Python/2.7.6
日期:2014年9月16日星期二03:58:42 GMT
500内部服务器错误
内部服务器错误
服务器遇到内部错误,无法完成您的请求。服务器过载或应用程序中存在错误
有什么想法吗?你可以很容易地做到:
@app.route("/")
def home():
resp = flask.Response("Foo bar baz")
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
看和
但是我发现您还有一个问题,因为after\u请求
也应该正确处理它
编辑我刚刚注意到您已经在使用
make_response
,这是一种方法。就像我之前说的那样,在请求之后
也应该起作用。尝试通过curl点击端点,看看标题是什么:
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错误页面,在底部有这个页面(有助于curl命令)
这是我的工作
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()
使用烧瓶的
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
从
烧瓶。做出响应(*args)
有时有必要在视图中设置其他标题。由于视图不必返回响应对象,但可以返回一个由Flask本身转换为响应对象的值,因此向其添加标题变得很棘手。可以调用此函数而不是使用返回,您将得到一个响应对象,您可以使用它来附加标题
这就是如何在我的flask应用程序中添加标题的方法,它工作得非常好
@app.after_request
def add_header(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
return response
我们可以使用Flask应用程序上下文,使用
Flask.g
使用Flask.g
在Flask应用程序上下文中设置响应头的这种方法是线程安全的,可以用于从应用程序的任何文件设置自定义和动态属性,如果我们从任何帮助器类设置自定义/动态响应头,这将特别有用,也可以从任何其他文件访问(比如说像中间件等),这个flask.g
是全局的,仅对该请求线程有效
假设我想从该应用程序调用的另一个api/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)
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)
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)
文件:middleware.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)
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)
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)
从主类调用中间件
文件:main.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)
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)
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)
您可以在args中发送请求:还有表示法
返回响应(headers={'Access-Control-Allow-Origin':'*')
,这对我来说更干净。我建议使用中间件来解决这个问题,或者只使用flask cors扩展