我正在做一个Aiohttp的中间件,它可以自动添加尾部的斜线。Aiohttp要求当你定义一个url时,你要为你的路由列表中的每个路径定义两个路由,一个带尾部斜杠,一个不带。他们有一个中间件的例子来解决这个问题,它通过查找url是否没有以 /
并添加它,如果没有,但他们使用http 302重定向来告诉客户端转到新的uri。否则,一个相对的uri,如 /endpoint
将404而 /endpoint/
就可以了。
这是他们的中间件。https:/github.comaio-libsaiohttpblobmasteraiohttpweb_middlewares.py。
以他们的中间件为基础,我试图完成同样的事情,但不需要在客户端进行重定向。我希望只在服务器端进行处理。我目前的尝试如下所示,似乎在飞行中更新了请求,但我仍然得到一个404。
from aiohttp.web_urldispatcher import SystemRoute
def middleware(f):
f.__middleware_version__ = 1
return f
def trailing_slashes():
@middleware
async def impl(request, handler):
if isinstance(request.match_info.route, SystemRoute):
rel_url = str(request.rel_url)
if '?' in rel_url:
path, query = rel_url.split('?', 1)
query = f'?{query}'
else:
path = rel_url
query = ''
if not path.endswith('/'):
rel_url = f'{path}/{query}'
request = request.clone(rel_url=rel_url)
return await handler(request)
return impl
这是一个实现中间件的类,说明了这个问题。
from aiohttp import web
import slashes_mw
class ClassName(object):
def __init__(self):
self.app = web.Application(middlewares=[slashes_mw.trailing_slashes()])
self.app.add_routes(self.get_routes())
web.run_app(self.app, port=80, host='0.0.0.0')
def get_routes(self):
return [
web.get('/', self.handler),
web.get('/{name}/', self.handler)
]
def handler(self, request):
return web.Response(text='hello')
ClassName()
有什么想法吗?谢谢您的帮助。
我认为他们提出的重定向方法是非常正确的,因为路由根本不一样。但你可以尝试注册第二个 "版本 "的路由。
def get_routes(self):
return [
web.get('/', self.handler),
web.get('/{name}/', self.handler),
web.get('/{name}', self.handler)
]
这应该可以在服务器端处理你的问题(未经测试)。
根据我对框架的理解,你的方法是行不通的,因为特定的处理程序是在不同的中间件被调用之前选择的。如果你在中间件中调用处理函数,就不会再进行 "路由 "查找了。或者至少我是这样理解他们的文档的。https:/docs.aiohttp.orgenstableweb_advanced.html#middlewares。
可能也很有意思。https:/docs.aiohttp.orgenstableweb_quickstart.html#变量资源。