Скачать файл без отображения URL
История
У меня были якорные теги, показывающие имена файлов, которые при нажатии использовали для загрузки файла с S3 url. Теперь мой клиент требует, чтобы я скрывал URL-адрес и не показывал его при загрузке файла, а также использовал уникальное имя на S3, а не читаемое имя файла. При загрузке имя файла должно быть изменено на читаемое имя файла, указанное при загрузке.
Требования
Есть 2 требования
- Изменить имя файла при загрузке.
- Скрыть URL-адрес файла из Front End - View.
усилия
Усилие-1: использование тега привязки
Простейшим решением было создать временный тег привязки и использовать атрибут загрузки в этом теге привязки.
<a id="2135"></a>
<script>
function download(event) {
var fileData = getFileData(event);
var tempAnch = $('a').attr({href: fileData.url, download: fileData.name});
tempAnch.click();
tempAnch.remove();
};
</script>
Это загружает файл, но не меняет имя по некоторым причинам. Я не мог решить это после многих переделок.
Усилие 2: использование подхода Ajax
Теперь я попытался загрузить содержимое файла на стороне JS и сохранить его в файл.
$.ajax({
type: 'GET',
url: fileData.url,
dataType: 'text',
success: function(msg) {
var blob = new Blob([msg],
{type: fileData.mimeType});
saveAs(blob, fileData.name);
}
});
Теперь этот код сохраняет файл с требуемым именем, и содержимое для текстового файла такое же. Но для файла Excel или xlsx загруженный файл поврежден.
Есть ли какое-либо возможное решение для загрузки файлов xlsx, csv, txt или zip без показа URL-адреса пользователю и изменения имени файла при загрузке?
2 ответа
Это не работает так. Вы загружаете что-то, запрашивающий клиент знает, откуда это происходит. Если вы хотите сделать ссылку пригодной для использования только один раз или для конкретного человека, вам необходимо передать ее через сервер приложений.
Единственным другим решением будет создание пользователей / разрешений на уровне S3, но даже в этом случае URL будет показан в какой-то момент.
Я бы не рекомендовал менять имя файла при каждой загрузке.
Тем не менее, установите свой собственный веб-сервер, создайте ключ для загрузки и позвольте пользователю называть ваш URL вместо этого. По запросу вы можете доставить файл и аннулировать ключ.
Просто имейте в виду, что если загрузка занимает много времени, ресурс на вашем веб-сервере обычно блокируется. Дешевый хостинг PHP с примерами 1 и 1 хочет работать для более чем 10 одновременно работающих пользователей (я пробовал:-))
Несмотря на нелепость этого требования, вот как вы сообщаете браузеру, как вызывать загружаемый файл, когда файл сохраняется локально: вам нужен S3, чтобы добавить этот заголовок ответа:
Content-Disposition: attachment; filename="the-desired-name.ext"
Это можно сделать двумя способами:
Опция 1.
Когда вы загрузите файл на S3, отправьте этот заголовок. S3 будет возвращать его при каждой загрузке, и браузер будет использовать это имя файла.
Вариант 2
В вашем подписанном URL скажите S3 добавить этот заголовок в ответ. Это добавит &response-content-disposition=attac...
на подписанный URL, и S3 увидит это и добавит необходимый заголовок ответа.
То, как вы это сделаете, зависит от того, что вы используете для создания предварительно подписанного URL (т.е. какой SDK, или, если вы написали свой собственный, как я).
Кроме того, при создании предварительно подписанного URL-адреса есть малоизвестная функция, которая позволяет вам определить, кому вы дали подписанный URL-адрес, прямо в URL-адресе. Поскольку подписанные URL-адреса не могут быть изменены или подделаны без полной аннулирования URL-адреса, пользователю не рекомендуется "обмениваться" URL-адресами, которые они могут обнаружить, поскольку URL-адрес их идентифицирует.:) Как это сделать? Вы добавляете x-amz-meta-{anything}={anything-else}
на URL до подписания. Пример: ...&x-amz-meta-downloaded-by=michael-sqlbot&...
, Часть S3, которая проверяет URL, потребует наличия этих параметров, чтобы URL соответствовал подписи, но часть S3, которая фактически возвращает то, что загружается... игнорирует это.
Конечно... если вы не используете предварительно подписанные URL-адреса, то это реальная проблема, которая у вас есть... и скрытие URL-адреса - это просто попытка решить не ту проблему. Любой минимально искушенный пользователь может определить URL-адрес, и я бы сказал, что при попытке его скрыть невозможно добиться подлинного преимущества безопасности.