几乎所有的web项目都会使用http的协议,在日常工作中最常用的还是使用http处理文本信息,在处理常见的文本请求及文件格式例如png、gif、脚本等,各个浏览器都能够通过开发者工具看到内容信息。
碰到上传或者下载文件时,浏览器通常无法看到内容信息。例如使用Chrome浏览器上传文件时:
本文将从底层码流的角度解析上传文件是如何处理http本身的文本数据和文件的二进制数据的。
结论:
http上传文件时,将文件的二进制码流混在http请求报文的二进制码流中一并发送。服务器解析时,http原有的部分(如请求行、请求头部字段等)按文本解析,文件部分码流直接写入到目标文件中。
环境搭建
常见的方式是通过mime的方式上传文件。通过spring-boot搭建基本的文件上传页面(源代码)。关键代码如下:
java部分:
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
html部分:
<form method="POST" enctype="multipart/form-data" action="/">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
页面效果 :
本地环境搭建完成后,启动工程,浏览器这输入localhost:8080
获取上传文件的码流:
上传只包含一字节[6]的文件使用java构建二进制文件,在服务端将会收到如下的码流(不同环境可能存在一定的差别,不影响分析过程)获取http码流:
[80, 79, 83, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49,13, 10, 72, 111, 115, 116, 58, 32, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 56, 48, 56, 48, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 107, 101, 101, 112, 45, 97, 108, 105, 118, 101, 13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32, 50, 49, 51, 13