某天,与前端就一个图片展现问题做评论,他想要浏览器中输入的图片链接能够直接展现图片于浏览器上,而并非主动下载。

怎样能够做到呢?

简单搜索一番,得知只要将Response Header中的Content-Type设定为“image/png”即可。(png可换成jpeg等其它子类型。)

设定Content-Type之后,并未收效,图片仍然被下载下来。

经过另一位前端小哥提点,得知原因在于Content-Disposition:

content-type:image/webp
content-disposition:attachment;filename="colorhub.webp"

将Content-Dispostion中的attachment替换为inline后,完成了该效果——Chrome打开新标签页,输入图片地址,图片被展现出来。

待我改完之后,发现前端想要的效果是在页面中展现图片,并非新开标签页检查。

他是能够用以下形式做到的:

<imgclass="card-img-topphoto-preview"src="//cdn.colorhub.me/9z-fWrEX26w/rs:auto:0:500:0/g:ce/fn:colorhub/bG9jYWw6Ly8vNjAvMDIvMmJlZmFkNjMwOWQ3ZTdkZTMwYTI0YWYzODMyYTQzYzhiZDEzNjAwMi5qcGVn.webp"alt="食物,甜点,蛋糕"title="食物,甜点,蛋糕"style="width:auto;">

img标签中,只需要指定src即可,与Conetent-Disposition无关。

这新知识的获得,让我感觉到自己对Web开发的许多细节,是很不了解的。

不了解它,便测验了解它。为了解Content-Disposition的效果,所以有了本篇。

1. Content-Disposition是什么?

1.1 根底界说

界说来源于RFC 6266:

The Content-Disposition response header field is used to convey additional information about how to process the response payload, and also can be used to attach additional metadata, such as the filename to use when saving the response payload locally.

Content-Disposition回来头的意图是指定如何处理回来信息,也能够用来附加其它的元数据,比如保存内容时指定文件名称。

1.2 语法解析

整个Header的语法如下:

1.content-disposition="Content-Disposition"":"
2.disposition-type*(";"disposition-parm)
3.disposition-type="inline"|"attachment"|disp-ext-type
4.;case-insensitive
5.disp-ext-type=token
6.disposition-parm=filename-parm|disp-ext-parm
7.filename-parm="filename""="value
8.|"filename*""="ext-value
9.disp-ext-parm=token"="value
10.|ext-token"="ext-value
11.ext-token=<thecharactersintoken,followedby"*">

榜首反响,是看不懂的。能猜到的是,引号(“)包起来代表的是必须要的内容。

第2行disposition-type后面的“*(”的意思是?

持续谷歌,在RFC 5234 3.6和3.8当中找到了答案,原文是这样的:

读《HTTP: The Definitive Guide》(二),初看RFC

*的用法

在“*”号左右,能够有两个数字,两个数字代表着后面紧跟内容的最小重复次数与最大重复次数。

“*1(foo bar)”等价于“[foo bar]”,代表0个或者1个,即可有可无的意思。(与各种指令参数的写法是相同的。)

那么“*( “;” disposition-parm )”的意思则为,括号中的内容,能够没有,也能够有多个。

1.3 filename中的中文字符

关于filename介绍的原文太长,我不摘抄,请检查引证链接2中的4.3小节,此处只列出我的了解。

当需要保存文件的时分,“filename”和“filename*”参数提供了文件名称,当“filename”和“filename*”同时存在时,只要“filename*”收效。

“filename*”答应使用非ISO-8859-1中的字符,它可用的编码在RFC 5987中界说。

我在Django中试了一下:

resp=HttpResponse(file_obj.read())
resp['Content-Disposition']="inline;filename*=UTF-8''中文.pdf"
resp['Content-Type']='application/pdf'

浏览器中看到的内容如下:

Content-Disposition:=?utf-8?b?aW5saW5lOyBmaWxlbmFtZSo9VVRGLTgnJ+S4reaWhy5wZGY=?=

明显,是错误的,再搜了搜,看到Django中FileResponse有以下完成:

#django.http.response.py
classFileResponse(StreamingHttpResponse):
"""
AstreamingHTTPresponseclassoptimizedforfiles.
"""

#...

defset_headers(self,filelike):
"""
Setsomecommonresponseheaders(Content-Length,Content-Type,and
Content-Disposition)basedonthe`filelike`responsecontent.
"""

#...

iffilename:
disposition="attachment"ifself.as_attachmentelse"inline"
try:
filename.encode("ascii")
file_expr='filename="{}"'.format(filename)
exceptUnicodeEncodeError:
#我的测验,差了一个quote函数
file_expr="filename*=utf-8''{}".format(quote(filename))
self.headers["Content-Disposition"]="{};{}".format(
disposition,file_expr
)
elifself.as_attachment:
#假如没有姓名,是只要前面内容的,与上面文档中看到的内容一致
self.headers["Content-Disposition"]="attachment"

浏览器中的Header变成以下内容:

Content-Disposition:inline;filename*=UTF-8''%E4%B8%AD%E6%96%87.pdf

点击“另存为”,弹出来确认框中的文件名称,变成了“中文.pdf”。

展现中文字符,需要quote一下。

至此,我对回来头Content-Disposition,有了些了解。

3. 其它

这是我榜首次测验阅览RFC文档。RFC的全称是Request For Comments,它的简介如下:

Request For Comments(RFC),是一系列以编号排定的文件。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件。RFC文件是由Internet Society(ISOC)赞助发行。基本的互联网通信协议都有在RFC文件内详细阐明。RFC文件还额定加入许多在规范内的论题,例如关于互联网新开发的协议及开展中一切的记载。因此简直一切的互联网规范都有收录在RFC文件之中。(摘自百度百科。)

通过RFC查询字段界说时,我发现RFC文档关于单词(”MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”)的使用,都是有明确规定的。

以MUST举例:

MUST This word, or the terms “REQUIRED” or “SHALL”, mean that the definition is an absolute requirement of the specification. (MUST意味着,这个界说是规范的绝对要求,完成者必须完成该界说。)

测验阅览RFC,让我对HTTP,又多了些了解——不管是Django或是Chrome,都是按规范办事的。

4. 引证链接

  1. 一个关于Content-Disposition的评论:stackoverflow.com/questions/1…
  2. RFC 6266:www.rfc-editor.org/rfc/rfc6266
  3. RFC 5234:datatracker.ietf.org/doc/html/rf…
  4. 附原文链接。