method 发表于 2025/12/21 17:03

kangle cdn 不能缓存 lua 输出的 base64 图片文本流

Kangle CDN 是否默认不缓存 text/plain / 动态 content_by_lua 响应?是否需要开启“缓存全部/Cache Everything”之类功能?

需要满足哪些条件(固定文件后缀、特定 Content-Type、禁止 gzip、必须有 Content-Length 等)Kangle 才会缓存?

是否建议改成专用路径如 /anime_b64/...,或把 Content-Type 改成 application/octet-stream / application/json 才能被缓存?

Kangle 上有没有“忽略 Cookie/忽略某些头/忽略参数”的设置,否则会导致永远 MISS?
=============
困挠了一年的问题
下面贴出 源站的 nginx 配置 和 lua代码

# cat image2binary.lua
-- /opt/image2base64.lua(保留 dataURL 的 text/plain 版)
local ROOT_PREFIX_URI = "/anime"
local ROOT_DIR      = "/anime"

local function read_file(p)
local f = io.open(p, "rb"); if not f then return nil end
local d = f:read("*a"); f:close(); return d
end

local uri = ngx.var.uri or ""
if not uri:find("^" .. ROOT_PREFIX_URI .. "/") then return ngx.exit(404) end
local rel = uri:sub(#ROOT_PREFIX_URI + 2)
if rel == "" or rel:find("%.%.", 1, true) or rel:find("\0") then return ngx.exit(400) end

local disk = ROOT_DIR .. "/" .. rel
local bin= read_file(disk); if not bin or #bin == 0 then return ngx.exit(404) end

local ext = (disk:match("%.(+)$") or ""):lower()
local mime = ({png="image/png", jpg="image/jpeg", jpeg="image/jpeg",
               gif="image/gif", webp="image/webp", svg="image/svg+xml",
               avif="image/avif", bmp="image/bmp", ico="image/x-icon"})
            or "application/octet-stream"

local data_url = "data:" .. mime .. ";base64," .. ngx.encode_base64(bin)
local etag = '"' .. ngx.md5(bin) .. '"'
local inm= ngx.req.get_headers()["If-None-Match"]

ngx.header["ETag"]         = etag
ngx.header["Content-Type"] = "text/plain; charset=utf-8"
ngx.header["Content-Length"]= #data_url
-- ⚠️ Cache-Control 让 Nginx 统一发,这里不再写

if inm and inm == etag then return ngx.exit(304) end
if ngx.req.get_method() == "HEAD" then return ngx.exit(200) end

ngx.print(data_url)


=============

server {
    listen 80;
    server_name *.manba-img.cfd *.mb-img.sbs *.mbjdvfkisdgn560ty.sbs;

    # 仅处理 /anime/ 下的文件(Lua 读磁盘并原样二进制输出)
    location /anime/ {
    # 彻底关压缩,避免 br/gzip 变体
    gzip off;
    gzip_vary off;
    # 如果装了 brotli:
    # brotli off;

    # 不要再用 expires 生成第二条 Cache-Control
    expires off;

    # 只设置一份 Cache-Control(浏览器 + 中间层)
    add_header Cache-Control "public, max-age=31536000, s-maxage=31536000, immutable" always;

    # CORS:只在这里发一份(如果决定让 Kangle 发,那这里就不要再发)
    add_header Access-Control-Allow-Origin"*" always;
    add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always;
    add_header Access-Control-Allow-Headers "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" always;
    add_header Access-Control-Max-Age "86400" always;
    if ($request_method = OPTIONS) { return 204; }

    content_by_lua_file /opt/image2binary.lua;# 或 image2base64.lua,二选一
    }   

    # 其它请求直接 404
    location / { return 404; }

    # ❌ 不要再加全局 Cache-Control(会造成重复同名头)
    # add_header Cache-Control "max-age=2592000";

    error_log/home/lualog/error.log;
    access_log off;
}



小樱 发表于 2025/12/21 18:23

只要是静态文件,kangle就会自动默认缓存,并且支持last-modified和etag、"vary"自动刷新缓存更新最新的文件,能缓存的只有get
如果要设置不缓存某个文件,可以在回应控制使用response_flag模块,或者请求控制使用flag模块,两则二选一,也可同时设置,互不冲突,请求控制模块的优先级最高
参考:https://bbs.itzmx.com/thread-98155-1-1.html

出现缓存miss的原因是浏览器缓存,小白常见问题,因为已经缓存在浏览器中,自然不需要和服务器拿新信息,显示miss正常的
https://bbs.itzmx.com/thread-95091-1-1.html

忽略header信息强制缓存一般适用于php动态链接,静态如上所述是自动缓存的,只有api、搜索之类的涉及到mysql数据库的动态内容可采取强制缓存设置
https://bbs.itzmx.com/thread-7562-1-1.html

kangle对于curl上传图片header base64限制长度在8M,图片原则上不能转成base64存入header来curl上传,应该直接使用PUT模式或者post
参考:https://bbs.itzmx.com/thread-92498-1-1.html

method 发表于 2025/12/21 18:50

樱大大
我的源站存的是 常规的 图片格比 比如 gif png jpg wepb
是在源站使用 lua 在线响应 cdn 回源 返回base64 文本 给到前端
前端引用的也是 jpg 这种正常请求格式,只是通过 js 把base64 文本 渲染成图片
现在 kangle cdn 没法缓存 base64 文本,一直都是回源了
如何解决

小樱 发表于 2025/12/21 21:20

method 发表于 2025/12/21 18:50
樱大大
我的源站存的是 常规的 图片格比 比如 gif png jpg wepb
是在源站使用 lua 在线响应 cdn 回源 返 ...

如果你看不懂我上面说的,你可以把链接发出来看看
然后你要点击回复按钮,不然收不到帖子提醒

method 发表于 2025/12/21 21:22

谢谢樱大,找到原因了,在处理了
页: [1]
查看完整版本: kangle cdn 不能缓存 lua 输出的 base64 图片文本流