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

如何基于MIME类型为Nginx代理的内容设置Expires响应头?

如何基于MIME类型为Nginx代理的内容设置Expires响应头?

嘿,我来帮你捋捋这个问题——你遇到的核心问题其实是Nginx在处理代理内容时,获取上游服务返回的MIME类型的正确姿势,以及配置细节上的小坑。

首先得说清楚:你最开始用$sent_http_content_type是行不通的,因为这个变量代表的是Nginx准备发送给客户端的Content-Type头,而在代理场景下,当Nginx执行expires指令的时候,这个值还没被完全确定下来,所以用它来匹配肯定得不到想要的结果。

你后来换成$upstream_http_content_type的思路是完全对的,这个变量才是上游服务(也就是你的Django应用)返回的Content-Type头的值。至于为什么还是没生效,大概率是下面几个原因之一,咱们一个个解决:

1. 先确认上游是否真的返回了Content-Type头

先用curl测一下你的代理接口,看看上游有没有返回这个关键头:

curl -I https://example.com/你的代理路径

如果输出里没有Content-Type这一行,那$upstream_http_content_type就是空的,map会匹配default规则(也就是off),自然不会添加Expires头。这种情况你得先去Django那边配置,确保接口返回正确的Content-Type。

2. 调整Map的匹配规则,兼容大小写和额外参数

很多时候上游返回的Content-Type可能带有大小写差异(比如Text/HTML)或者附加参数(比如text/html; charset=utf-8),你原来的map匹配是严格的字符串匹配,很容易漏匹配。建议改成忽略大小写的正则匹配:

map $upstream_http_content_type $expires2 {
    default                    off;
    # 用~*开启忽略大小写的正则匹配
    ~*text/html                2d;
    ~*text/plain               20d;
    ~*text/css                 180d;
    ~*application/font-woff2   1y;
    ~*application/pdf          1y;
    ~*image/                   1y;
}

这样不管上游返回的是text/html还是Text/HTML; charset=utf-8,都能正确匹配到对应的过期时间。

3. 给expires指令加上always参数

如果上游服务自己返回了Cache-Control头,Nginx默认不会用expires指令的结果去覆盖它。这时候你需要加上always参数,强制让Nginx设置Expires头:

location / {
    uwsgi_pass django;
    # 加上always,确保不管上游有没有返回缓存头,都按我们的规则设置Expires
    expires $expires2 always;
}

完整的配置示例

把这些调整整合起来,最终的配置大概是这样:

# 针对上游返回的Content-Type设置过期规则
map $upstream_http_content_type $expires2 {
    default                    off;
    ~*text/html                2d;
    ~*text/plain               20d;
    ~*text/css                 180d;
    ~*application/font-woff2   1y;
    ~*application/pdf          1y;
    ~*image/                   1y;
}

server {
    listen       443 ssl http2;
    server_name  example.com;

    location / {
        uwsgi_pass django;
        expires $expires2 always;
    }

    # 静态文件的配置保留你原来的即可
    location ~ ^/(css|fonts|images|pdf|html)/ {
        root /var/www/django/static/;
        expires $expires;
    }
}

最后别忘了测试和重载

修改完配置后,先检查配置是否合法:

nginx -t

没问题的话就重载Nginx:

nginx -s reload

测试的时候记得清空浏览器缓存,或者用curl加上-H "Cache-Control: no-cache"参数,避免旧缓存干扰结果。

备注:内容来源于stack exchange,提问作者janeden

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:38:00