如何在Flask中返回相对URI位置头?

12 投票
1 回答
13917 浏览
提问于 2025-04-18 00:01

Flask在构建我的HTTP响应时,会替换掉我的Location头部的内容。它把我原本的相对URI的Location头部改成了绝对URI。

@app.route('/votes', methods=['POST'])
def votes():
    return jsonify(), 201, {'location': '/votes/1'}

这是我的测试:

def test_vote_creation(self):
    response = self.app.post('/votes',
                             data=json.dumps({
                                 'name': 'Test vote'
                             }), content_type='application/json')
    print(response.headers['location'])

返回的是http://localhost/votes/1,而不是/votes/1

如何用Flask的jsonify返回一个相对URI的Location头部?

补充说明:根据当前的HTTP/1.1标准RFC 2616,Location头部的值必须是一个绝对URI。不过,RFC将会修改,允许使用相对URI。因此,我想改变我的API的默认行为,让它在Location头部返回相对URI。

更多细节可以查看这篇文章

1 个回答

11

HTTP规范规定,Location这个头信息必须是一个完整的URI(统一资源标识符):

14.30 Location

Location响应头字段用于将接收者重定向到一个不同于请求URI的位置,以完成请求或识别一个新资源。对于201(已创建)响应,Location是由请求创建的新资源的位置。对于3xx响应,Location应该指示服务器希望自动重定向到资源的URI。这个字段的值由一个完整的URI组成。

Location       = "Location" ":" absoluteURI

因此,Flask / Werkzeug的响应对象会把任何相对URL的Location头信息转换为一个完整的URL。

可以改变这种行为,虽然我不建议这样做。如果要改变,可以将Response对象的autocorrect_location_header属性设置为Falsejsonify()会返回一个响应对象,你可以修改它:

@app.route('/votes', methods=['POST'])
def votes():
    response = jsonify()
    response.status_code = 201
    response.headers['location'] = '/votes/1'
    response.autocorrect_location_header = False
    return response

但请注意,即使Flask不强制要求,你的WSGI服务器仍然可以强制使用完整的URL。

撰写回答