今天翻出 N 年前画的一个上传文件数据格式图,供大家参考。
注意这是文件上传,或文件文本混合上传的时候,即 enctype="multipart/form-data" 的时候的格式。
在 ASP.NET 中,由于封装了上传类,所以可以很方便地读取上传文件的数据内容,而 ASP 中,需要我们根据其数据结构单独写,理解了下面的数据结构,我们不仅可以很方便地实现任意文件的上传保存,还可实现一个或多个文件,甚至文字混合的上传保存。
再给个直观的示例
这个示例是我们在 ASP.NET 中构造一个表单,然后用 Request.SaveAs 保存下来的。
可以看出前面是 Header 部分,后面是 Body 部分。
我们先简单看下 Header 部分。
如果我们不是通过浏览器上传,而是通过 WebClient 一类的程序上传,不指定 Content-Length 也可以,它会自动帮我们加上。
然后下一行:Content-Type 为 multipart/form-data,然后 boundary 为较复杂的字符串,您可能会说如果我们的内容中就有这些字符串,且不是要被 Request 误判,好像还真是这么回事,所以浏览器会每次随机生成这个字符串,也就是说每次看到的不一样,以减少重复机率。另外这里 boundary 以 ---- 开头,我们自己构造的话,不必。
我们重点讨论下 Body 部分。
- 每个数据项以 --boundary 作为开始行,注意 boundary 前面有 --,因为 boundary 本身自己也带了 --,所以如果不小心会看漏。
- 然后是 Content-Disposition,注意文本值和文件值略有不同。注意这里面有个 name 叫:p%22>> 2,这是我故意这么搞的,其实客户端的名字叫:p">> 2,可以看出 " 被转为 %22 ,> 被转为 >,其他不变。
- 【文本省略此行】下一行是 Content-Type:,这个我们自己构造的话,也可以不构造,这其中第 good 由于没有传文件,所以浏览器为其指定的值为:application/octet-stream。
- 换行,注意噢,有个换行,内容才正式开始。
- 内容,内容无值也要占一行。
- 【文本或无内容的上传文件,省略此行】换行。
- 【文本或无内容的上传文件,省略此行】换行。
最后
body 的各个参数项循环完后,以 --boundary-- 结束。
总结一下
文本部分
- 第一行为此文本项的开始标识:--boundary
- 第二行为此文本项的头部:Content-Disposition: form-data; name="..."
- 第三行为此文本项头部与身体的分隔行:空行
- 第四行为此文本项身体的开始,结束后要补一个 \r\n,前面的各行也补了,只是它们最多就只占一行,所以没特别说明,而文本项身体可能占多行,容易忘记,所以强调一下。
文件部分
- 第一行为此文件项的开始标识:--boundary
- 第二行为此文件项的头部:Content-Disposition: form-data; name="..."; filename="..."
- 第三行为此文件项的头部:Content-Type: ...,可省略此行。
- 第四行为此文件项头部与身体的分隔行:空行
- 第五行为此文件项身体的开始,结束后要补一个 \r\n,前面的各行也补了,只是它们最多就只占一行,所以没特别说明,而文件项身体可能占多行,容易忘记,所以强调一下。
- 然后再写入 2 个 \r\n,加上上一步的 \r\n,一共会产生 3 个空行,不过因为后面还要写数据,所以实际最终只有 2 个空行。
最后