什么是中间件
视频锁定
{$ currentTime | date:'mm:ss' $}
{$ timeLeft | date:'mm:ss' $}
我们从一个简单的例子开始。
高流量的站点通常需要将Django部署在负载平衡proxy(参见第20章)之后。 这种方式将带来一些复杂性,其一就是每个request中的远程IP地址(request.META["REMOTE_IP"]
)将指向该负载平衡proxy,而不是发起这个request的实际IP。负载平衡proxy处理这个问题的方法在特殊的 X-Forwarded-For
中设置实际发起请求的IP。
因此,需要一个小小的中间件来确保运行在proxy之后的站点也能够在 request.META["REMOTE_ADDR"]
中得到正确的IP地址:
class SetRemoteAddrFromForwardedFor(object):
def process_request(self, request):
try:
real_ip = request.META['HTTP_X_FORWARDED_FOR']
except KeyError:
pass
else:
# HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.
# Take just the first one.
real_ip = real_ip.split(",")[0]
request.META['REMOTE_ADDR'] = real_ip
(注意,虽然HTTP header中的key是"X-Forwarded-For"
,但是Django将它放在request
对象META属性中时的key为"HTTP_X_FORWARDED_FOR"
。除了内容大小和类型之外,其余任何在request
中的HTTP头信息都会被Django转换为大写字母加下划线这种方式,而且最后会加上HTTP_"前缀。)
一旦安装了该中间件(参见下一节),每个request
中的 X-Forwarded-For
值都会被自动插入到 request.META['REMOTE_ADDR']
中。这样,Django应用就不需要关心自己是否位于负载平衡proxy之后;简单读取 request.META['REMOTE_ADDR']
的方式在是否有proxy的情形下都将正常工作。
实际上,为针对这个非常常见的情形,Django已将该中间件内置。 它位于 django.middleware.http
中,下一节将给出这个中间件相关的更多细节。
在线练习
{$ activeFileHint $}