You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx负向location规则失效求助:非doc/img路径未返回418

Nginx负向Location匹配问题求助

URL示例

1) /store/doc/some_file.doc
2) /store/doc/some_dir/some_file.doc
3) /store/img/some_file.doc
4) /store/img/some_dir/some_file.doc
5) /store/xxx/some_file.doc
6) /store/xxx/some_dir/some_file.doc

当前Nginx配置

location /storage/ {
   location ^~/storage/[^(doc|img)]/(.*) {
       return 418;
   }
   rewrite ^/storage/(doc|img)/(.*) /storage/_storage.php?type=$1&file=$2 break;
}

需求说明

  • 所有以/storage/开头的URL需进行特定处理
  • 若URL不匹配/storage/doc/*或/storage/img/*,返回418状态码("I'm teapot")
  • 若URL匹配/storage/doc/*或/storage/img/*,将请求转发至/storage/_storage.php,并携带GET参数:type(取值为doc或img)、file(对应路径后的剩余部分)

当前问题

URL1-4处理正常,但URL5和6未返回418状态码,需要正确的Nginx负向location条件写法。


问题原因

原配置中的[^(doc|img)]是单个字符排除集合,它仅匹配不属于(、d、o、c、|、i、m、g、)的单个字符,而非整个路径段。因此像/storage/xxx/这类路径不会被匹配,自然不会返回418。

解决方案

方案一:利用Location优先级(推荐)

通过先匹配合法路径,剩余请求统一返回418,符合Nginx的匹配逻辑:

location /storage/ {
    # 优先匹配doc/img路径,转发到处理脚本
    location ~ ^/storage/(doc|img)/(.*)$ {
        rewrite ^/storage/(doc|img)/(.*) /storage/_storage.php?type=$1&file=$2 break;
        # 若需处理PHP请求,需补充fastcgi_pass等配置,此处保留原逻辑
    }
    # 其他/storage/开头的请求直接返回418
    return 418;
}

Nginx中正则Location(~)优先级高于前缀Location,因此合法请求会被优先处理,剩下的全部触发418。

方案二:使用if指令配合否定正则

适合简单场景,直接判断请求URI是否不符合合法路径:

location /storage/ {
    if ($request_uri !~ ^/storage/(doc|img)/) {
        return 418;
    }
    rewrite ^/storage/(doc|img)/(.*) /storage/_storage.php?type=$1&file=$2 break;
}

!~表示不匹配后续正则,符合条件的请求直接返回418。

方案三:用负向前瞻修正嵌套Location

如果坚持使用嵌套Location结构,可借助正则负向前瞻断言匹配非doc/img的路径段:

location /storage/ {
    location ~ ^/storage/(?!doc|img)/ {
        return 418;
    }
    rewrite ^/storage/(doc|img)/(.*) /storage/_storage.php?type=$1&file=$2 break;
}

(?!doc|img)是负向前瞻,匹配不是doc或img开头的路径段,从而正确拦截非法请求。


内容的提问来源于stack exchange,提问作者DarkVss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:16:17