NGINX 从 proxy_pass 响应中读取正文

Kli*_*mbo 8 lua nginx proxypass

我有两台服务器:

  1. NGINX(它将文件 id 交换为文件路径)
  2. Golang(它接受文件 id 并返回它的路径)

例如:当浏览器客户端向 发出请求时https://example.com/file?id=123,NGINX 应将此请求代理到 Golang 服务器https://go.example.com/getpath?file_id=123,后者会将响应返回给 NGINX:

{
  data: {
    filePath: "/static/..."
  },
  status: "ok"
}
Run Code Online (Sandbox Code Playgroud)

然后 NGINX 应该从 filePath 获取值并从该位置返回文件。

所以问题是如何在 NGINX 中读取响应(获取文件路径)?

Max*_*hny 7

我假设您是软件开发人员并且您可以完全控制您的应用程序,因此无需在此处将方钉强制插入圆孔中。

不同种类的反向代理支持ESI(Edge Side Includes)技术,允许开发者用静态文件的内容或上游服务器的响应体替换响应体的不同部分。

Nginx 也有这样的技术。它被称为SSI(服务器端包含)

location /file {
    ssi on;
    proxy_pass http://go.example.com;
}
Run Code Online (Sandbox Code Playgroud)

您的上游服务器可以生成包含内容的正文,<!--# include file="/path-to-static-files/some-static-file.ext" -->并且nginx 将使用文件的内容替换此 in-body 指令

但是你提到了流媒体...

这意味着文件将具有任意大小,并且使用SSI构建响应肯定会消耗宝贵的 RAM资源,因此我们需要一个Plan #B

有一种“足够好”的方法可以将大文件提供给客户端,而无需向客户端显示文件的静态位置。您可以使用 nginx 的错误处理程序根据上游服务器提供的信息来处理静态文件。例如,上游服务器可以发回重定向 302,其中包含指向文件的真实文件路径的位置标头字段。此响应不会到达客户端,而是被送入错误处理程序。

下面是一个配置示例:

location /file {
    error_page 302 = @service_static_file;
    proxy_intercept_errors on;
    proxy_set_header Host            $host;
    proxy_pass http://go.example.com;
}

location @service_static_file {
    root /hidden-files;
    try_files $upstream_http_location 404.html;
}
Run Code Online (Sandbox Code Playgroud)

使用此方法,您将能够在不使系统过载的情况下提供文件,同时可以控制向谁提供文件。

为此,您的上游服务器应以状态 302 和典型的“位置:”字段响应,nginx 将使用位置内容在静态文件的“新”根目录中查找文件。

这种方法是“足够好”类型(而不是完美)的原因是因为它不支持部分请求(即范围:字节...)