好久不见~
为什么我会有疑问?
最近要做个下载文件的功能,当后端说做好了给我接口的时候,我直接拼上参数然后window.open(url)之后,浏览器为什么没有像从前一样下载啊?我又换了个姿势还是不行,我感觉后端给的接口不对,但是后端是个实习生,于是我们就开始面向google编程了,结果在我们共同的努力下真的解决了!将主要知识点总结如下:
浏览器如何对文件进行嗅探的?
content-type相关
当浏览器访问某个地址后,会对返回结果头中的content-type的进行检查。content-type的值是遵循MIME标准的。
MIME用来表示文档、文件或字节流的性质和格式。
MIME 的组成结构非常简单;由类型与子类型两个字符串中间用'/'分隔而组成。不允许空格存在。格式:type/subType
下面是几种比较常见的类型:
- text/plain 文本文件默认值。浏览器可以直接展示。
- application/octet-stream 程序文件的默认值。浏览器一般不会自动执行或询问执行,消息体会被下载到本地。
- text/css :在网页中要被解析为 CSS 的任何 CSS 文件必须指定 MIME 为
text/css
。 - text/javascript:据 HTML 标准,应该总是使用 MIME 类型
text/javascript
服务 JavaScript 文件 - image/png:png图片
所以接口的response header中content-type: application/octet-stream是这样婶的浏览器就会自动下载
content-depostion相关
通过上面的介绍我们已经知道需要设置正确的content-type才能让浏览器识别文件。但是有个问题,那我想要下载一个png怎么办?
那么我们此时就要用到content-depostion了,这个响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。
请看3个例子:
代码语言:javascript复制Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.png"
示例代码如下:
代码语言:javascript复制router.get('/abc.json', (ctx) => {
ctx.type = 'image/png';
ctx.set('Content-Disposition', 'attachment; filename="abc.png"');
// 上面两行代码,可以简写成 ctx.attachment('hello.json');
ctx.body = {
kk: 'mm',
};
});
备注:上面设置的type就是content-type;
参考:https://juejin.cn/post/6844903773597335560