ChatGPT解决这个技术问题 Extra ChatGPT

Python Flask,如何设置内容类型

我正在使用 Flask,并从 get 请求中返回一个 XML 文件。如何将内容类型设置为 xml ?

例如

@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    header("Content-type: text/xml")
    return xml

S
Simon Sapin

试试这样:

from flask import Response
@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    return Response(xml, mimetype='text/xml')

实际的 Content-Type 基于 mimetype 参数和字符集(默认为 UTF-8)。

此处记录了响应(和请求)对象:http://werkzeug.pocoo.org/docs/wrappers/


是否可以在全局级别(即:默认)设置这些和其他选项?
@earthmeLon,创建 flask.Response 的子类,覆盖 default_mimetype 类属性,并将其设置为 app.response_class werkzeug.pocoo.org/docs/wrappers/… flask.pocoo.org/docs/api/#flask.Flask.response_class
@earthmeLon:如果您像 Simon 指出的那样设置 app.response_class,请记住使用 app.make_response 来获取您的响应实例,例如 pointed out in the answer below
使用浏览器或邮递员的请求可以很好地使用这种方法,但是 curl 不能很好地使用返回的 Response 对象。卷曲只会打印“找到”。使用 curl “返回内容、状态码、标题”似乎效果更好。
l
lmat - Reinstate Monica

就这么简单

x = "some data you want to return"
return x, 200, {'Content-Type': 'text/css; charset=utf-8'}

希望能帮助到你

更新:使用下面的方法,因为它适用于 python 2.x 和 python 3.x,并且它消除了“多头”问题(可能发出多个重复的头)。

from flask import Response
r = Response(response="TEST OK", status=200, mimetype="application/xml")
r.headers["Content-Type"] = "text/xml; charset=utf-8"
return r

最简单的解决方案。绝对应该是公认的答案
有一个缺点:它只允许您添加标题。当我这样做时,我最终得到了两个 Content-Type 标题作为响应 - 默认一个并添加了一个。
@omikron我已经更新了答案,尝试它应该工作的新方法。
@HarshDaftary 我不清楚哪个是新方法,哪个是旧方法。您能否将“此方法”替换为“上面的方法”或“下面的方法”?
@Leo 我添加了所需的说明。
M
Michael Wolf

我喜欢并赞成@Simon Sapin 的回答。然而,我最终采取了稍微不同的策略,并创建了自己的装饰器:

from flask import Response
from functools import wraps

def returns_xml(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        r = f(*args, **kwargs)
        return Response(r, content_type='text/xml; charset=utf-8')
    return decorated_function

并这样使用它:

@app.route('/ajax_ddl')
@returns_xml
def ajax_ddl():
    xml = 'foo'
    return xml

我认为这会更舒服一些。


当同时返回响应和状态码(如 return 'msg', 200)时,这将导致 ValueError: Expected bytes。相反,将装饰器更改为 return Response(*r, content_type='whatever')。它将元组解包为参数。不过,谢谢你,一个优雅的解决方案!
t
ti7

使用 make_response method 获取您的数据的响应。然后设置 mimetype attribute。最后返回这个响应:

@app.route('/ajax_ddl')
def ajax_ddl():
    xml = 'foo'
    resp = app.make_response(xml)
    resp.mimetype = "text/xml"
    return resp

如果您直接使用 Response,您将失去通过设置 app.response_class 自定义响应的机会。 make_response 方法使用 app.responses_class 来生成响应对象。在此您可以创建自己的类,添加使您的应用程序全局使用它:

class MyResponse(app.response_class):
    def __init__(self, *args, **kwargs):
        super(MyResponse, self).__init__(*args, **kwargs)
        self.set_cookie("last-visit", time.ctime())

app.response_class = MyResponse  

这本质上是@SimonSapin 接受的重新包装的答案。
@J0e3gan 谢谢。我扩展了我的答案,以更好地解释为什么使用 make_response 比使用 Response 更好
R
Ryan Liu
from flask import Flask, render_template, make_response
app = Flask(__name__)

@app.route('/user/xml')
def user_xml():
    resp = make_response(render_template('xml/user.html', username='Ryan'))
    resp.headers['Content-type'] = 'text/xml; charset=utf-8'
    return resp

我认为这个答案很重要,因为它清楚地说明了如何从 render_template 更改某些内容的标题。
z
zhengGuo

您可以尝试以下方法(python3.6.2):

案例一:

@app.route('/hello')
def hello():

    headers={ 'content-type':'text/plain' ,'location':'http://www.stackoverflow'}
    response = make_response('<h1>hello world</h1>',301)
    response.headers = headers
    return response

案例二:

@app.route('/hello')
def hello():

    headers={ 'content-type':'text/plain' ,'location':'http://www.stackoverflow.com'}
    return '<h1>hello world</h1>',301,headers

我正在使用 Flask 。如果你想返回 json,你可以这样写:

import json # 
@app.route('/search/<keyword>')
def search(keyword):

    result = Book.search_by_keyword(keyword)
    return json.dumps(result),200,{'content-type':'application/json'}


from flask import jsonify
@app.route('/search/<keyword>')
def search(keyword):

    result = Book.search_by_keyword(keyword)
    return jsonify(result)

l
lord63. j

通常您不必自己创建 Response 对象,因为 make_response() 会为您处理好这些。

from flask import Flask, make_response                                      
app = Flask(__name__)                                                       

@app.route('/')                                                             
def index():                                                                
    bar = '<body>foo</body>'                                                
    response = make_response(bar)                                           
    response.headers['Content-Type'] = 'text/xml; charset=utf-8'            
    return response

还有一件事,好像没有人提到after_this_request,我想说点什么:

after_this_request

在这个请求之后执行一个函数。这对于修改响应对象很有用。该函数被传递给响应对象,并且必须返回相同的或新的。

所以我们可以用 after_this_request 来做,代码应该是这样的:

from flask import Flask, after_this_request
app = Flask(__name__)

@app.route('/')
def index():
    @after_this_request
    def add_header(response):
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        return response
    return '<body>foobar</body>'