首页 > 解决方案 > 使用 Aqueduct 提供的文件没有 Content-Length 标头

问题描述

我正在使用 Aqueduct 为我的 Flutter 应用程序编写后端。我设置了 Aqueduct,以便 Nginx 代理向它发出请求,如下所示:

server {

    root /home/web/my_server/web;
    index index.html index.htm;

    server_name example.com www.example.com;

    location / {
        try_files $uri $uri/ =404;
    }

    location /api {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://127.0.0.1:8888;
        proxy_http_version 1.1;
    }

    ...
}

在 Aqueduct 中,我使用以下方式提供文件FileController

router.route("/api/v1/app/*")
    .link(() => LogController(context))
    .link(() => FileController("public/app/")
  ..setContentTypeForExtension('apk', ContentType('application', 'vnd.android.package-archive')));

但是,它返回的任何文件都不包含 Content-Length 标头。这意味着我无法显示下载进度。

我尝试创建一个自定义 FileController,在其中手动添加了标题:

final contentLengthValue = file.lengthSync();

return Response.ok(byteStream,
    headers: {HttpHeaders.lastModifiedHeader: lastModifiedDateStringValue,
      HttpHeaders.contentLengthHeader: contentLengthValue,
      'x-decompressed-content-length': contentLengthValue,
      HttpHeaders.cacheControlHeader: 'no-transform',
      HttpHeaders.acceptRangesHeader: 'bytes'})
  ..cachePolicy = _policyForFile(file)
  ..encodeBody = false
  ..contentType = contentType;

Content-Length 标头仍被删除,但x-decompressed-content-length标头仍然存在,因此这是一种可能的解决方法。它只是不能很好地与一些寻找 Content-Length 标头并且没有方便的方法来检查其他标头的 Flutter 插件配合使用。

这是 Aqueduct 问题还是 Nginx 问题?我该如何解决?

标签: flutterdarthttp-headersaqueducthttp-content-length

解决方案


该解决方案有效,但它绕过了原始问题。也就是说,它允许您提供在标题中具有 Content-Length 的文件,但它没有解释为什么它在 Aqueduct 中被剥离。欢迎其他答案。

与其让 Aqueduct 服务文件,不如让 Nginx 直接服务它们。

如果你不能改变你的 API 路由,你可以在 Nginx 配置位置块中给它一个别名。/api在位置块之前添加它。

location /api/v1/app/ {
    alias /home/web/my_server/public/app/;
}

现在文件app/夹中的文件将由 Nginx 而不是 Aqueduct 提供。Nginx 在它返回的文件中包含 Content-Length 标头。


推荐阅读