上传文件需要使用 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFIc14z39Lb6Leu6y ;
- multipart/form-data 是文件传输的content-type 格式
- boundary 是分隔符,分隔多个文件、表单项。如果不自己设置,默认由浏览器自动产生
1. 使用方式
1.1 html 表单点击提交
enctype=“multipart/form-data”, method=post, type=“file” 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。
<form action="upFile.php" enctype="multipart/form-data" method="post">
<input name="myflie" type="file" />
<input type="submit" />
1.2 通过api 提交文件
通过FormData 对象将文件数据传入。
content-type 设置为false 或者不写。浏览器会自动识别为multipart/form-data;并设置boundary 分割符号
// FormData创建
const formData = new FormData();
formData.append('file', blob);
formData.append('updateMode', 'false');
// api调用
const httpOptions = {
headers: new HttpHeaders({
// 'Content-Type': 'multipart/form-data', 自动会生成Content-Type
Authorization: sessionStorage.getItem('Authorization')
})
};
this.http.post(``, formData, { observe: 'response', ...httpOptions }).pipe(
catchError(this.shareService.handleError())
);
2. 概念
在最初的 http 协议中,没有上传文件方面的功能。 rfc1867为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。
3. multipart-formdata 作用
为了上传文件,等二进制流
4. boundary 分割符号
4.1自定义boundary
- 给文件流设置分隔符
- 给content-type 设置同样的分割符
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input type="file" id="file">
<button id="trigger">trigger</button>
<script type="text/javascript">
var file = document.getElementById("file");
var trigger = document.getElementById("trigger");
trigger.addEventListener("click", function(e){
var reader = new FileReader();
reader.readAsDataURL(file.files[0].slice());
reader.addEventListener("loadend", function(e){
req = new XMLHttpRequest();
req.overrideMimeType("text/plain");
req.addEventListener("load", function(e){
var img = document.createElement("img");
img.src = e.target.response;
document.body.appendChild(img);
}, false);
req.open("post", "./tmp_50.php");
var sBoundary = "---------------------------" + Date.now().toString(16);
req.setRequestHeader("Upgrade-Insecure-Requests", "1");
req.setRequestHeader("Content-Type", "multipart\/form-data; boundary=" + sBoundary);
var data = new Blob(["--" + sBoundary + "\r\n" + "Content-Disposition: form-data; name=\"payload\"; filename=\"payload.data\"" + "\r\n" + "Content-Type: application/octet-stream" + "\r\n" + "\r\n", reader.result, "\r\n" + "--" + sBoundary + "--" + "\r\n"], {type : 'application/octet-stream'});
req.send(data);
});
4.2 浏览器自动生成分隔符
不设置 content-type 浏览器就会自动识别,并生成
headers: new HttpHeaders({
// 'Content-Type': 'multipart/form-data',
Authorization: sessionStorage.getItem('Authorization')
})