在nginx中有没有一种方法可以根据请求体是否有字符串来做一些事情?我相信我可以用Lua模块来做。我想知道是否有一种方法可以单独使用nginx。
我希望下面这样的东西能起作用。
location /students-api {
if ($request_body ~* "(.*)specialstudent(.*)" ) {
set $student_status 'special';
}
// and use student_status for some logic
}
1条答案
按热度按时间pod7payv1#
我认为它应该工作,但它需要测试。在实践中,我只使用
$request_body
进行日志记录,不确定它是否在请求处理的重写阶段可用。这里有一个官方的描述说:当请求体被读取到内存缓冲区时,变量的值在
proxy_pass
、fastcgi_pass
、uwsgi_pass
和scgi_pass
指令处理的位置可用。此外,如果以后不使用这些捕获组,您不需要它们来检查变量是否存在子字符串(实际上,将它们保存在内存中只是浪费资源),只需
if ($request_body ~* "specialstudent") { ... }
就足够了。更新
下面是另一种更有可能工作的方法,因为
proxy_add_header
指令肯定会在请求处理的重写阶段之后执行:更新2
在测试了所有这些之后,我可以确认
if
方法不起作用:正如预期的那样,
$request_body
变量不会在请求处理的重写阶段初始化。但是,map
方法可以按预期工作:真正让我惊讶的是,下面的例子没有设置两个头中的任何一个:
在请求处理的早期重写阶段访问
$request_body
变量会导致map
转换也停止工作。我现在没有解释这种行为,如果有人能解释这里发生了什么,我会很感激。更新3
我想我终于找到了解释Nginx教程中最后一个例子发生了什么的解释,这是由著名的lua-nginx-module和OpenResty包的作者Yichun Zhang编写的:
一些Nginx变量选择在配置“get handler”时使用它们的值容器作为数据缓存。在此设置中,“获取处理程序”仅运行一次,即,在变量第一次被读取时,这减少了变量在其生命周期期间被多次读取时的开销。
如果在
NGX_HTTP_REWRITE_PHASE
早期访问$request_body
变量,则看起来$request_body
变量的行为完全相同(请参阅请求处理阶段描述)。如果在该阶段读取了它的值,则会将其缓存为空值,并在后续的请求处理阶段变得无用。