задний план
Во второй половине рабочего дня ко мне подошел фронтенд-друг и сказал: "Моя онлайн-страница оказалась в порядке. Почему она стала загружаемой, когда я зашел сегодня? Я ничего не делал?" В этот момент некоторые люди также сообщили, что все веб-страницы были загружены при доступе к ним.
После срочного расследования было установлено, что причиной проблемы стал некий Alibaba CloudCDN
Возникла проблема со сборкой запроса возврата узла к источнику, в результате чегоOSS
Происхождение не может быть признаноCDN
запросить и вставитьcontent-disposition
заголовок, который в конечном итоге влияет на логику обработки файла браузером. (Он должен быть отображен браузером и загружен как вложение).
Итак, о чем я хочу поговорить с вами сегодня, так это о том, что вызвало эту онлайн-проблему.Content-disposition
Как это свято.
Content-Disposition
Content-Disposition
Есть два сценария применения.
Используется в заголовках ответов HTTP
Сценарий 1 используется в заголовках ответов HTTP, чтобы указать, как должно отображаться содержимое ответа. Будь то встроенная форма (то есть веб-страница или часть страницы) или загруженная и сохраненная локально в виде вложения.
Content-Disposition
Первый параметр имеет два значения:
-
inline
Значение по умолчанию, означающее, что тело сообщения в ответе отображается как часть страницы или как вся страница. -
attachment
Тело сообщения, представляющее ответ, должно быть загружено локально; большинство браузеров отобразит диалоговое окно «сохранить как».
Второй параметр является необязательнымfilename
.当响应的内第一个参数指定为attachment
, браузер загрузит содержимое ответа,filename
Можно указать имя загруженного файла.
Content-Disposition
В заголовках ответов это может выглядеть так:
// 正常解析渲染
Content-Disposition: inline
// 下载文件
Content-Disposition: attachment
// 下载文件,并将文件保存为filename.jpg
Content-Disposition: attachment; filename="filename.jpg"
Используется в теле запроса multipart/form-data
Другой сценарий заключается в том, что когда на странице есть форма, и метод отправки формы, который мы выбираем,multipart/form-data
час,Content-Disposition
Он появится в теле запроса. Его роль заключается в том, чтобы проиллюстрировать, какое имя поля соответствующей формы, какое имя файла, загруженного в форму. Первый параметр в этой сцене всегда фиксирован.form-data
, с двумя дополнительными необязательными параметрами.name
Указывает имя поля соответствующего элемента формы,filename
Указывает имя соответствующего загруженного файла. использовать между параметрами;
разделять.
Content-Disposition
существуетmultipart/form-data
Заголовок тела запроса может выглядеть следующим образом:
Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"
Пример
Далее, давайте углубим наше впечатление об этом на примере. Этот пример в основном демонстрирует две части функции.
- установив
Content-Disposition: attachment
Загрузите файл, который сохраняет запрос в вашем браузере. - Проиллюстрируйте, реализуя почтовый запрос
Content-Disposition: form-data
Форма представления в теле запроса.
СоздайтеcontentDispositionDemo
каталог, выполнить:
npm install express multiparty
Код сервера, который мы используемexpress
добиться, используяmultiparty
модуль для обработкиmultipart/form-data
запрос. Код сервера выглядит следующим образом:
// app.js
const express = require("express");
const multiparty = require("multiparty");
const app = express();
const port = 3000;
app.use(express.static("public"));
// 访问的时候,弹窗提示下载attachment.html,并保存为ddd.html
app.get("/attach", (req, res, next) => {
const options = {
root: __dirname,
headers: {
"Content-Disposition": "attachment;filename=ddd.html"
}
};
res.sendFile("/attachment.html", options, err => {
if (err) {
next(err);
} else {
console.log("Sent:", "attachment.html");
}
});
});
// form-data表单提交
app.post("/user", (req, res, next) => {
const form = new multiparty.Form();
var name;
var image;
form.on("error", next);
form.on("close", function(err) {
console.log(err);
console.log(name);
console.log(image);
res.send("资料提交成功!");
});
form.on("field", function(key, val) {
if (key !== "image") name = val;
});
form.on("part", function(part) {
if (!part.filename) return;
if (part.name !== "image") return part.resume();
image = {};
image.filename = part.filename;
image.size = 0;
part.on("data", function(buf) {
image.size += buf.length;
});
});
form.parse(req);
});
app.listen(port, () => console.log(`App listening on port ${port}!`));
Затем мы создаем простую страницу отправки формы, где пользователю необходимо ввести свое имя и фотографию. мы помещаем эту страницу вpublic
В каталоге код страницы следующий:
<!--public/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>content-disposition 示例</title>
<style>
form {
padding: 20px;
border: 1px gray solid;
background: yellowgreen;
}
.form-item {
padding: 10px 0;
}
#commit {
display: block;
width: 80px;
height: 30px;
text-align: center;
line-height: 30px;
border: 1px solid #666;
cursor: pointer;
background: #eee;
}
</style>
</head>
<body>
<h1>请提交您的个人资料</h1>
<form>
<div class="form-item">
<label for="name">姓名:</label>
<input type="text" name="name" id="name" />
</div>
<div class="form-item">
<label for="pic">照片:</label>
<input type="file" name="image" id="image" />
</div>
<div class="form-item"><span id="commit">提交</span></div>
</form>
</body>
<script>
function upload() {
var formData = new FormData();
var name = document.querySelector("#name").value;
var image = document.querySelector("#image").files[0];
formData.append("name", name);
formData.append("image", image);
var xhr = new XMLHttpRequest();
xhr.open("POST", "/user");
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
alert(xhr.responseText);
}
};
xhr.send(formData);
}
document.querySelector("#commit").addEventListener(
"click",
function() {
upload();
},
false
);
</script>
</html>
Кроме того, создайте еще одну HTML-страницу, которая будет использоваться для загрузки при доступе к ней браузера. Конкретное содержание кода является необязательным:
<!--attachment.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>保存文件</title>
</head>
<body>
保存文件
</body>
</html>
воплощать в жизньnode app.js
Запустить сервис, когда мы посетимlocalhost:3000/attach
, вы можете обнаружить, что браузер загружает напрямуюattachment.html
, и сохраните его какddd.html
.
Ниже приведен скриншот страницы загрузки:
Ниже приведен скриншот заголовка ответа:
доступlocalhost:3000
, вводим информацию в форму на главной странице и отправляем ее, после чего мы видим следующее изображениеContent-Disposition
форма отображения:
Суммировать
С тех пор, как мы используемContent-Disposition
По умолчаниюinline
не отображается в заголовке ответа запроса, поэтому я предполагаю, что многие внешние партнеры могутContent-Disposition
Не знаю достаточно. Его основная цель — сообщить браузеру, что делать с содержимым ответа. Конечно, случайность в начале статьи была случайностью. Получив более подробное представление об этом в этой статье, я считаю, что друзья, работающие с интерфейсом, могут умело использовать его для достижения различных целей.
насчет нас
Передовая команда Kuaigou Taxi занимается обменом передовыми технологиями и регулярно публикует высококачественные статьи. Добро пожаловать, обратите внимание и лайкните.
Статья будет опубликована в паблике одновременно, если вы хотите получать актуальную информацию как можно быстрее, просто отсканируйте ее!