NGINX URI编码匹配问题:无法通过请求URI匹配映射中的URI
解决NGINX编码URI批量重定向匹配问题
方案一:利用$request_uri和map指令(静态批量匹配)
NGINX的$request_uri变量保存了原始编码状态的完整请求URI(包括查询参数),正好可以匹配你带%20、%29等编码字符的规则。
操作步骤
整理重定向规则文件
创建一个map格式的规则文件(比如/etc/nginx/conf.d/redirects.map),每条规则按"原始编码URI" "目标URI";格式写入:"/blogpost/november%20twentysixth" "/new-blog/november-26"; "/post/hello%29world" "/new-post/hello-world"; # 剩余52998条规则依次写入如果需要忽略查询参数,可将规则改为正则匹配开头:
~^/blogpost/november%20twentysixth(\?.*)?$ "/new-blog/november-26";在NGINX主配置中引入规则
在http块中定义map,然后在server块中判断并执行重定向:http { # 其他全局配置... map $request_uri $redirect_target { include /etc/nginx/conf.d/redirects.map; default ""; # 无匹配时返回空字符串 } server { # 其他server配置... if ($redirect_target != "") { return 301 $redirect_target; } } }
方案二:Lua脚本实现(灵活处理大数量规则)
如果map指令的正则性能无法满足需求,或者需要更复杂的逻辑,可借助NGINX Lua模块(推荐用OpenResty)实现。
操作步骤
编写Lua规则表
创建Lua文件(比如/etc/nginx/conf.d/redirects.lua),将重定向规则存为键值对table:local redirect_map = { ["/blogpost/november%20twentysixth"] = "/new-blog/november-26", ["/post/hello%29world"] = "/new-post/hello-world", -- 剩余规则依次添加 } return redirect_map在NGINX配置中调用Lua脚本
在server块中通过access_by_lua_block加载规则并处理重定向:server { # 其他server配置... access_by_lua_block { local redirect_map = require("redirects") # 提取原始编码的请求路径(去掉查询参数) local request_path = ngx.var.request_uri:match("^([^%?]+)") local target_uri = redirect_map[request_path] if target_uri then # 避免循环重定向:判断目标是否与当前路径一致 if target_uri ~= request_path then return ngx.redirect(target_uri, 301) end end } }
关键注意事项
- 批量导入规则前,务必用少量测试规则验证配置,避免NGINX启动失败。
- 若使用map指令,
map块必须放在http层级,不能嵌套在server或location内。 - 重定向目标URI需避免与原始规则的编码URI重复,防止循环重定向。
内容的提问来源于stack exchange,提问作者Vin Hegewald
相关产品推荐
相关产品推荐

