Sanic框架中的请求与响应头处理指南

Sanic框架中的请求与响应头处理指南

sanic Accelerate your web app development | Build fast. Run fast. sanic 项目地址: https://gitcode.com/gh_mirrors/sa/sanic

头部信息概述

在Sanic框架中,请求头和响应头分别通过RequestHTTPResponse对象提供。这些头部信息使用了multidict数据结构,允许单个键对应多个值。

重要特性:Sanic在解析头部信息时会将所有键名转换为小写形式,这意味着头部信息的键名是大小写不敏感的。

请求头处理

Sanic对请求头进行了智能处理,不仅提供了标准化的访问方式,还针对常见用例进行了特殊提取。

授权令牌处理

Sanic可以自动识别并提取以下格式的授权令牌:

  • Token <token>
  • Bearer <token>

提取后的令牌可以通过request.token直接访问:

@app.route("/")
async def handler(request):
    return text(request.token)

测试示例:

curl localhost:8000 -H "Authorization: Token ABCDEF12345679"
# 输出: ABCDEF12345679

curl localhost:8000 -H "Authorization: Bearer eyJhbGci..."
# 输出: eyJhbGci...

代理头处理

Sanic对代理头有特殊处理逻辑,这部分内容属于高级主题,将在专门的代理头章节详细介绍。

主机头与动态URL构建

request.host提供了"有效主机"信息,它可能与实际的主机头不同,因为它会优先考虑代理转发的主机,并受服务器名称配置的影响。

app.config.SERVER_NAME = "https://example.com"

@app.route("/hosts", name="foo")
async def handler(request):
    return json({
        "effective host": request.host,
        "host header": request.headers.get("host"),
        "forwarded host": request.forwarded.get("host"),
        "you are here": request.url_for("foo"),
    })

安全提示:动态构建的URL可能被恶意客户端通过伪造主机头操纵。如果安全性是首要考虑,应使用app.url_for替代request.url_for

通用头信息访问

所有请求头都可以通过request.headers以字典形式访问,键名大小写不敏感:

@app.route("/")
async def handler(request):
    return json({
        "foo_weakref": request.headers["foo"],
        "foo_get": request.headers.get("Foo"),
        "foo_getone": request.headers.getone("FOO"),
        "foo_getall": request.headers.getall("fOo"),
        "all": list(request.headers.items()),
    })

访问方法说明

  • .get().getone():获取第一个匹配的值
  • .getall():获取所有值的列表

请求ID处理

X-Request-ID头可以通过request.id便捷访问:

@app.route("/")
async def handler(request):
    return text(request.id)

响应头处理

Sanic会自动设置以下响应头(在适当情况下):

  • content-length
  • content-type
  • connection
  • transfer-encoding

开发者通常无需手动设置这些头部。

自定义响应头

可以通过路由处理器或响应中间件添加自定义响应头:

# 直接在路由中设置
@app.route("/")
async def handler(request):
    return text("Done.", headers={"content-language": "en-US"})

# 通过中间件设置
@app.middleware("response")
async def add_csp(request, response):
    response.headers["content-security-policy"] = "default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';base-uri 'self';form-action 'self'"

自动请求ID处理

一个常见的中间件用例是为所有响应添加X-Request-ID头。即使请求中没有提供ID,Sanic也会自动生成一个:

@app.on_response
async def add_request_id_header(request, response):
    response.headers["X-Request-ID"] = request.id

最佳实践建议

  1. 在构建URL时优先使用app.url_for而非request.url_for,以避免主机头欺骗
  2. 访问头部信息时,使用.get().getone()方法获取单个值
  3. 对于需要严格安全控制的响应,使用中间件统一添加安全相关的头部
  4. 利用request.id实现全链路请求追踪

通过合理利用Sanic提供的头部处理功能,开发者可以构建更加安全、可维护的Web应用程序。

sanic Accelerate your web app development | Build fast. Run fast. sanic 项目地址: https://gitcode.com/gh_mirrors/sa/sanic

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郝钰程Kacey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值