前言

最近需要使用 apisix 反向代理 oss, 实现通过域名访问相应的资源(由于条件的限制,不能在oss绑定自定义域名),我直接在 apisix dashboard 配置了路由,创建成功后,我通过浏览器访问时,发现资源不能预览会直接下载。

这样的现象让我很奇怪,通过查阅相关资料,发现使用OSS默认域名通过文件URL从浏览器访问图片或者网页文件时,Response Header中会自动加上Content-Disposition:attachment。 即从浏览器访问这些文件时,会以附件形式进行下载。

解决

通过询问同事,得知他是通过 nginx 的 proxy_hide_header 忽略 Content-Disposition 解决的。 那 apisix 该怎么实现呢,我通过自己的不断尝试和提 issue 询问官方人员,得知可以使用 response-rewrite 插件实现这个功能。

接下来我就来介绍下我尝试的过程吧,我最开始是使用 proxy-rewrite 将 Content-Disposition 设置为 inline,具体配置如下:

{
  "uri": "/*",
  "name": "xx",
  "host": "xixi.xx.work",
  "plugins": {
    "proxy-rewrite": {
      "headers": {
        "Content-Disposition": "inline"
      },
      "host": "xx",
      "regex_uri": [
        "/(.*)$",
        "/xx/${1}"
      ]
    }
  },
  "upstream": {
    "nodes": [
      {
        "host": "xxx.com",
        "port": 80,
        "weight": 1
      }
    ],
    "timeout": {
      "connect": 6,
      "send": 6,
      "read": 6
    },
    "type": "roundrobin",
    "scheme": "http",
    "pass_host": "pass",
    "keepalive_pool": {
      "idle_timeout": 60,
      "requests": 1000,
      "size": 320
    }
  },
  "status": 1
}

curl 结果:

$ curl -I xxk/index.html
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5556
Connection: keep-alive
Date: Sat, 05 Nov 2022 06:45:06 GMT
Vary: Accept-Encoding
Accept-Ranges: bytes
ETag: "xxx"
Last-Modified: Wed, 02 Nov 2022 10:27:56 GMT
Content-Disposition: attachment
Content-MD5: ExxA==
Server: APISIX/2.13.3

可以看到 Content-Disposition: attachment 没有改变。

接下来我尝试使用 response-rewrite 插件进行,我的配置如下:

img.png

curl 后发现还是没有成功,后来通过issue问题回答的帮助得知我所使用的 apisix 2.13.3 不支持 Remove/Add/Set Header 操作, Remove/Add/Set Header 操作 是3.0 版本才增加的功能,最后我的配置如下:

{
  "uri": "/*",
  "name": "xx",
  "host": "xixxxe.work",
  "plugins": {
    "proxy-rewrite": {
      "host": "xx.aliyuncs.com",
      "regex_uri": [
        "/(.*)$",
        "/xx/${1}"
      ]
    },
    "response-rewrite": {
      "disable": false,
      "headers": {
        "Content-Disposition": ""
      },
      "vars": [
        [
          "status",
          "==",
          200
        ]
      ]
    }
  },
  "upstream": {
    "nodes": [
      {
        "host": "xx.aliyuncs.com",
        "port": 80,
        "weight": 1
      }
    ],
    "timeout": {
      "connect": 6,
      "send": 6,
      "read": 6
    },
    "type": "roundrobin",
    "scheme": "http",
    "pass_host": "pass",
    "keepalive_pool": {
      "idle_timeout": 60,
      "requests": 1000,
      "size": 320
    }
  },
  "status": 1
}

curl 结果:

$ curl -I xx.work/index.html
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5556
Connection: keep-alive
Date: Sat, 05 Nov 2022 06:59:00 GMT
Vary: Accept-Encoding
Accept-Ranges: bytes
Last-Modified: Wed, 02 Nov 2022 10:27:56 GMT
Server: APISIX/2.13.3

小结

本文介绍了如何使用 apisix 实现 nginx proxy_hide_header 相同的操作。

参考