Nginx中日语URL映射编码文件名无法访问问题求助
解决Nginx中URL编码文件名无法匹配请求的问题
问题原因
Nginx接收到包含非ASCII字符的URL请求时,会自动对URL进行解码,将/2012年日本の旅/转换成对应的UTF-8字符路径,再去文件系统中查找。但你的文件存储在URL编码后的路径/2012%e5%b9%b4%e6%97%a5%e6%9c%ac%e3%81%ae%e6%97%85/下,自然无法匹配,导致404错误。
解决方案
方案1:使用第三方模块重编码路径(推荐)
借助ngx_set_misc模块的set_encode_uri指令,将解码后的路径重新编码,让Nginx匹配编码后的文件路径。
- 确保Nginx已编译
ngx_set_misc模块(源码编译时添加--add-module=path/to/ngx_set_misc参数)。 - 在Nginx的
server块中添加配置:
# 提取请求路径(去除查询参数) if ($request_uri ~* ^(/[^?]+)) { set $original_path $1; } # 先解码路径,再重新编码 set_unescape_uri $decoded_path $original_path; set_encode_uri $encoded_path $decoded_path; # 尝试访问编码后的路径下的index.html try_files $encoded_path/index.html $encoded_path =404;
- 重启Nginx:
nginx -s reload
方案2:用Lua脚本实现路径编码(无需额外模块)
利用Nginx的Lua模块编写脚本,手动处理路径编码:
- 确保Nginx已编译
ngx_http_lua_module模块(源码编译时添加--add-module=path/to/lua-nginx-module)。 - 在
server块中添加配置:
location ~* ^/ { content_by_lua_block { -- 提取不带查询参数的请求路径 local raw_uri = ngx.var.request_uri:match("^(/[^?]+)") if not raw_uri then ngx.status = 404 ngx.say("404 Not Found") return end -- 先解码原路径,再重新编码 local decoded_uri = ngx.unescape_uri(raw_uri) local encoded_uri = ngx.escape_uri(decoded_uri) -- 拼接文件路径(根据实际根目录调整) local root_dir = ngx.var.document_root local file_path = root_dir .. encoded_uri .. "/index.html" -- 检查文件是否存在 local file = io.open(file_path, "r") if file then file:close() ngx.exec(encoded_uri) else ngx.status = 404 ngx.say("404 Not Found") end } }
- 重启Nginx生效。
方案3:批量重命名文件(最简单)
直接将URL编码的文件夹批量重命名为原日文字符,适配Nginx默认的路径匹配逻辑:
# 遍历当前目录下的URL编码文件夹并解码重命名 for dir in */; do decoded_dir=$(echo "$dir" | perl -MURI::Escape -ne 'print uri_unescape($_)') mv "$dir" "$decoded_dir" done
内容的提问来源于stack exchange,提问作者Doraemon
相关产品推荐
相关产品推荐

