Нужен ли Content-Type: application / octet-stream для загрузки файла?

414

Стандарт HTTP гласит:

Если этот заголовок [Content-Disposition: attachment] используется в ответе с типом содержимого application / octet-stream, подразумевается, что пользовательский агент не должен отображать ответ, а непосредственно вводит `save response как .. Диалог.

Я читаю это как

Content-Type: application/octet-stream
Content-Disposition: attachment

Но я бы подумал , что Content-Typeбыло бы application/pdf, image/pngи т.д.

Должен ли я иметь, Content-Type: application/octet-streamесли я хочу, чтобы браузеры загружали файл?

Пол Дрейпер
источник

Ответы:

959

Нет.

Тип контента должен быть таким, каким он известен, если вы это знаете. application/octet-streamопределяется как «произвольные двоичные данные» в RFC 2046, и здесь есть определенное совпадение того, что они подходят для сущностей, единственной целью которых является сохранение на диск, и с этого момента они должны находиться вне чего-либо «webby». Или посмотреть на это с другой стороны; единственное, что можно безопасно сделать с помощью application / octet-stream, - это сохранить его в файл и надеяться, что кто-то еще знает, для чего он нужен.

Вы можете комбинировать использование Content-Dispositionс другими типами контента, такими как image/pngили даже, text/htmlчтобы указать, что вы хотите сохранить, а не отобразить. Раньше было так, что некоторые браузеры игнорировали бы это в случае, text/htmlно я думаю, что это было довольно давно в этот момент (и я скоро ложусь спать, поэтому я не собираюсь начинать тестировать целую кучу браузеры прямо сейчас, может быть позже).

RFC 2616 также упоминает о возможности маркеров расширения, и в настоящее время большинство браузеров признают, inlineчто вы хотите, чтобы сущность отображалась, если это возможно (то есть, если это тип, который браузер знает, как отображать, в противном случае у него нет выбора). , Это, конечно, поведение по умолчанию в любом случае, но это означает, что вы можете включить filenameчасть заголовка, которую будут использовать браузеры (возможно, с некоторой настройкой, чтобы расширения файлов соответствовали локальным системным нормам для рассматриваемого типа контента, возможно, нет) в качестве предложения, если пользователь пытается сохранить.

Следовательно:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"

Означает «Я не знаю, что это за чертовщина. Пожалуйста, сохраните его как файл, желательно с именем picture.png».

Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"

Означает «Это изображение в формате PNG. Пожалуйста, сохраните его как файл, желательно с именем picture.png».

Content-Type: image/png
Content-Disposition: inline; filename="picture.png"

Означает «Это изображение в формате PNG. Пожалуйста, покажите его, если вы не знаете, как отображать изображения в формате PNG. В противном случае, или если пользователь решит сохранить его, мы рекомендуем имя picture.png для файла, в котором вы сохраняете его как».

Из тех браузеров, которые распознают inlineнекоторые, всегда будут использовать его, в то время как другие будут использовать его, если пользователь выбрал «сохранить ссылку как», но не если он выбрал «сохранить» во время просмотра (или, по крайней мере, раньше IE был таким, возможно, изменился несколько лет назад).

Джон Ханна
источник
30
Это был отличный ответ, и было бы здорово, если бы все работало так. Но, к сожалению, все браузеры в основном не работают. Например, Google Chrome не откроет для вас окно «сохранения файла», если это ваш ответ из формы, независимо от того, включен ли «Content-Disposition: attachment», даже с «application / octet-stream» в качестве типа контента , А потом они печатают сообщение о том, что вы можете быть атакованы ... Просто нет способа разрешить мне сохранить файл. Вы должны настроить xdg-open, даже если вы просто хотите сохранить файл. Мне это надоело.
Divybyzero
1
@dividebyzero не проблема, с которой я когда-либо сталкивался, в том числе и с Chrome. Есть ли что-то необычное в том, что вы делаете?
Джон Ханна
1
Загрузка файла с заданным по умолчанию типом enctype будет некорректной, и, возможно, результатом этого станет некоторое обнаружение атаки, а не просто падение, чтобы сделать содержимое файла доступным.
Джон Ханна
7
@ Если клиент хочет сохранить его, то не имеет значения, какие заголовки отправляются (вы можете «сохранить» или «сохранить ссылку как» в любом браузере), поскольку заголовки являются информацией, а не правилами, которые attachmentмогут быть считается "лучше не показывать это самому", inlineа "лучше всего показывать это самому, если можете". В любом случае, большинство браузеров будут использовать значение имени файла в качестве рекомендуемого имени файла, но пользователи всегда могут переопределить это.
Джон Ханна
1
@ Тресдин, спасибо. Я немного озадачен тем, что он настолько популярен по сравнению с некоторыми из моих других, которые я бы посчитал лучше, но я полагаю, что он, должно быть, попал в точку ответа на вопросы людей.
Джон Ханна