После некоторого, опыта решил написать небольшую статью-шпаргалку о загрузке файлов с использованием возможностей HTML5, а именно File API.
- Поддержка браузерами.
- Загрузка через Form Data.
- Загрузка через File Reader.
1. Поддержка браузерами
Конечно же не все браузеры на данный момент поддерживают в полной мере эту возможность. Про IE благополучно забываем, так как он будет поддерживать File API только в 10 версии. С остальными, более прогрессивными браузерами, а это всего лишь Chrome, Firefox, Opera и Safari, тоже не все так гладко. Они конечно стараются быть «вперде», но пока не у всех получается.
В HTML 5 существует 2 способа считать и асинхронно отправить файл на сервер: через объекты File Reader и Form Data. В принципе, именно для загрузки файлов разницы нет, каким способом отправлять файлы на сервер. Если говорить совсем точно, то за отправку файлов несет ответственность объект XMLHttpRequest, а File Reader и Form Data всего лишь позволяют считать файл и «скормить» его XHR.
как загрузить «залить» файл «программу» в интернет.
Эти объекты предназначены для разных задач. File Reader предназначен для работы с файлами на стороне браузера. То есть еще до загрузки файла на сервер можно узнать его параметры, такие как вес, тип, дата создания и т. п. Картинки, например, можно сразу показывать пользователю, не загружая их на сервер. Form Data предназначен для создания форм и управления данными форм до загрузки на сервер.
А как мы знаем, в формах и присутствует input type=«file», через который до этого момента мы и отправляли файлы. Таким образом можно создать форму, прикрепить к ней файл и через XHR отправить ее на сервер.
От лирики к делу. Рассмотрим оба примера загрузки. Но прежде небольшая заметка о том, что неплохо было бы определять возможности браузера по загрузке через File API. Для этого достаточно проверить наличие объектов File Reader или Form Data. Но!
Safari до сих пор не сделал поддержку File Reader и работать с этим объектом у вас не получится. Яблофаги негодуют, а мы любим всех пользователей одинаково. Поэтому на данный момент самой правильной проверкой будет считаться наличие Form Data:
if (window.FormData === undefined) < // Сообщаем отсталым браузерам, что они отсталые 🙂 Либо делаем альтернативную загрузку. >
2. Загрузка через Form Data
Сначала описываем все события: перетаскивание файлов, «бросание» их в блок для загрузки и т. п.
$(«#drop-block»).bind( // #drop-block блок куда мы будем перетаскивать наши файлы ‘dragenter’, function(e) < // Действия при входе курсора с файлами в блок. >) .bind( ‘dragover’, function(e) < // Действия при перемещении курсора с файлами над блоком. >).bind( ‘dragleave’, function(e) < // Действия при выходе курсора с файлами за пределы блока. >).bind( ‘drop’, function(e) < // Действия при «вбросе» файлов в блок. if (e.originalEvent.dataTransfer.files.length) < // Отменяем реакцию браузера по-умолчанию на перетаскивание файлов. e.preventDefault(); e.stopPropagation(); // e.originalEvent.dataTransfer.files — массив файлов переданных в браузер. // e.originalEvent.dataTransfer.files[i].size — размер отдельного файла в байтах. // e.originalEvent.dataTransfer.files[i].name — имя отдельного файла. // Что какбэ намекает 🙂 upload(e.originalEvent.dataTransfer.files); // Функция загрузки файлов. >>);
Ну и закодим непосредственно чтение и загрузку файлов:
Как загрузить файл на гугл диск и отправить ссылку
function upload(files) < // Сначала мы отправим пустой запрос на сервер. // Это связано с тем, что иногда Safari некорректно обрабатывает // первый файл. $.get(‘/blank.html’); var http = new XMLHttpRequest(); // Создаем объект XHR, через который далее скинем файлы на сервер. // Процесс загрузки if (http.upload http.upload.addEventListener) < http.upload.addEventListener( // Создаем обработчик события в процессе загрузки. ‘progress’, function(e) < if (e.lengthComputable) < // e.loaded — сколько байтов загружено. // e.total — общее количество байтов загружаемых файлов. // Кто не понял — можно сделать прогресс-бар 🙂 >>, false ); http.onreadystatechange = function () < // Действия после загрузки файлов if (this.readyState == 4) < // Считываем только 4 результат, так как их 4 штуки и полная инфа о загрузке находится if(this.status == 200) < // Если все прошло гладко // Действия после успешной загрузки. // Например, так // var result = $.parseJSON(this.response); // можно получить ответ с сервера после загрузки. >else < // Сообщаем об ошибке загрузки либо предпринимаем меры. >> >; http.upload.addEventListener( ‘load’, function(e) < // Событие после которого также можно сообщить о загрузке файлов. // Но ответа с сервера уже не будет. // Можно удалить. >); http.upload.addEventListener( ‘error’, function(e) < // Паникуем, если возникла ошибка! >); > var form = new FormData(); // Создаем объект формы. form.append(‘path’, ‘/’); // Определяем корневой путь. for (var i = 0; i < files.length; i++) < form.append(‘file[]’, files[i]); // Прикрепляем к форме все загружаемые файлы. >http.open(‘POST’, ‘/upload.php’); // Открываем коннект до сервера. http.send(form); // И отправляем форму, в которой наши файлы. Через XHR. >
3. Загрузка через File Reader
File Reader собственно и предназначен для работы с файлами на стороне браузера. Попробуем загрузить файлы при помощи этого объекта. Напоминаем, что в Safari нет объекта File Reader!
if (window.FileReader === undefined) < // Проверяем наличие объекта в браузере // Если нет — негодуем! >// Для перетаскивания файлов используются все те же события. // Но мы напишем их немного в другом виде, для разнообразия. // Без комментариев. var dropbox = $(‘#file-drag’); dropbox[0].ondragover = function() < return false; >; dropbox[0].ondragleave = function() < return false; >; dropbox[0].ondrop = function(e) < var files = e.dataTransfer.files; uploadFile(files[i]); e.preventDefault(); e.stopPropagation(); return false; >; // Внимательный пользователь заметит некоторые отличия. // Во-первых, события привязываем к 0 элементу массива объекта. // Во-вторых, в функцию загрузки передаем по одному файлу. // Функция чтения и загрузки function uploadFile(file) < var reader = new FileReader(); reader.onload = function() < var xhr = new XMLHttpRequest(); xhr.upload.addEventListener(«progress-bar», function(e) < if (e.lengthComputable) < // Прогресс-бра, ага 😉 >>, false); // Помним про события load и error xhr.onreadystatechange = function () < if (this.readyState == 4) < if(this.status == 200) < >else < // Пичалька 🙁 >> >; xhr.open(«POST», «upload.php»); // Составляем заголовки и тело запроса к серверу, в котором и отправим файл. var boundary = «xxxxxxxxx»; // Устанавливаем заголовки. xhr.setRequestHeader(‘Content-type’, ‘multipart/form-data; boundary=»‘ + boundary + ‘»‘); xhr.setRequestHeader(‘Cache-Control’, ‘no-cache’); // Формируем тело запроса. var body = «—» + boundary + «rn»; body += «Content-Disposition: form-data; name=’superfile’; filename='» + unescape( encodeURIComponent(file.name)) + «‘rn»; // unescape позволит отправлять файлы с русскоязычными именами без проблем. body += «Content-Type: application/octet-streamrnrn»; body += reader.result + «rn»; body += «—» + boundary + «—«; // Пилюля от слабоумия для Chrome, который гад портит файлы в процессе загрузки. if (!XMLHttpRequest.prototype.sendAsBinary) < XMLHttpRequest.prototype.sendAsBinary = function(datastr) < function byteValue(x) < return x.charCodeAt(0) >var ords = Array.prototype.map.call(datastr, byteValue); var ui8a = new Uint8Array(ords); this.send(ui8a.buffer); > > // Отправляем файлы. if(xhr.sendAsBinary) < // Только для Firefox xhr.sendAsBinary(body); >else < // Для остальных (как нужно по спецификации W3C) xhr.send(body); >>; // Читаем файл reader.readAsBinaryString(file); >;
Данная статья является не инструкцией к применению, а всего лишь пособием для изучения возможностей HTML 5. Код не претендует на идеальность. Буду рад, если кто-то дополнит или поправит.
Источник: habr.com
Как загрузить файл в программу
Для отправки файлов на сервер HttpClient использует класс System.Net.Http.MultipartFormDataContent . Фактически этот класс выступает в качестве контейнера объектов HttpContent. А для добавления элементов в MultipartFormDataContent применяется метод Add()
public void Add(HttpContent content, string name, string fileName);
Первый параметр — отправляемое содержимое (это может быть как файлы, так и любые другие данные). Второй параметр — name определяет название данных в запросе, по которому мы можем получить файл на сервере. Третий параметр — fileName устанавливает имя файла.
Загрузка одного файла
Для тестирования загрузки файла определим приложение ASP.NET Core со следующим кодом:
var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.MapPost(«/upload», async (HttpContext context) => < // получем коллецию загруженных файлов IFormFileCollection files = context.Request.Form.Files; // путь к папке, где будут храниться файлы var uploadPath = $»/uploads»; // создаем папку для хранения файлов Directory.CreateDirectory(uploadPath); // пробегаемся по всем файлам foreach (var file in files) < // формируем путь к файлу в папке uploads string fullPath = $»/»; // сохраняем файл в папку uploads using (var fileStream = new FileStream(fullPath, FileMode.Create)) < await file.CopyToAsync(fileStream); >> await context.Response.WriteAsync(«Файлы успешно загружены»); >); app.Run();
Здесь метод app.MapPost() определяет конечную точку, которая обрабатывает запросы по пути «upload». В обработчике конечной точки в качестве параметра получаем контекст запроса HttpContext и через него с помощью свойства context.Request.Form.Files получаем коллекцию загруженных файлов. Далее пробегаемся по этой коллекции и сохраняем все данные в проекте в папке «upoload» (если ее нет, она создается).
Теперь определим клиент:
Итак, в моем случае веб-приложение запущено по адресу «»https://localhost:7094/», поэтому для обращения к конечной точке, которая получает файлы, я использую адрес «»https://localhost:7094/upload». Также в моем случае загружается файл «D:forest.jpg».
Для отправки создаем MultipartFormDataContent
using var multipartFormContent = new MultipartFormDataContent();
Обратите внимание на конструкцию using, которая позволит закрыть все связанные с объектом потоки, использованные при отправке файла.
Затем создаем объект StreamContent , который получает содержимое файла в виде файлового потока:
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
Устанавливаем mime-тип, который соответствует загружаемому файлу:
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(«image/jpeg»);
Далее добавляем этот объект в MultipartFormDataContent:
multipartFormContent.Add(fileStreamContent, name: «file», fileName: «forest.jpg»);
В конце отправляем файл и получаем ответ:
using var response = await httpClient.PostAsync(serverAddress, multipartFormContent); var responseText = await response.Content.ReadAsStringAsync();
Стоит отметить, что нам необязательно применять для отправки файла именно StreamContent. Например, можно считать данные файла в массив байтов и отправить его, используя класс ByteArrayContent :
Код сервера при этом остается тем же.
Множественная отправка файлов
Подобным образом можно отправлять и большее количество файлов. Например:
using System.Net.Http.Headers; class Program < static HttpClient httpClient = new HttpClient(); static async Task Main() < // адрес для отправки var serverAddress = «https://localhost:7094/upload»; // пути к файлам var files = new string[] < «D:forest.jpg», «D:cats.jpg» >; using var multipartFormContent = new MultipartFormDataContent(); // в цикле добавляем все файлы в MultipartFormDataContent foreach (var file in files) < // получаем краткое имя файла var fileName = Path.GetFileName(file); var fileStreamContent = new StreamContent(File.OpenRead(file)); fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(«image/jpeg»); multipartFormContent.Add(fileStreamContent, name: «files», fileName: fileName); >// Отправляем файлы using var response = await httpClient.PostAsync(serverAddress, multipartFormContent); // считываем ответ var responseText = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseText); > >
Отправка смешанного содержимого
Плюсом MultipartFormDataContent состоит в том, что он позволяет отправить смешенного содержимое, не только файлы. Например, пусть у нас веб-приложение ASP.NET получает некоторые данные:
using Microsoft.AspNetCore.Mvc; var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.MapPost(«/upload», async (HttpContext context) => < var form = context.Request.Form; // получаем отдельные данные string? username = form[«username»]; string? email = form[«email»]; // получаем коллецию загруженных файлов IFormFileCollection files = form.Files; // путь к папке, где будут храниться файлы var uploadPath = $»/uploads»; // создаем папку для хранения файлов Directory.CreateDirectory(uploadPath); foreach (var file in files) < // путь к папке uploads string fullPath = $»/»; // сохраняем файл в папку uploads using (var fileStream = new FileStream(fullPath, FileMode.Create)) < await file.CopyToAsync(fileStream); >> return $»Данные пользователя () успешно загружены»; >); app.Run();
На сервере теперь из коллекции context.Request.Form получаем данные с ключом «username» и «email» (условные имя и электронный адрес пользователя).
На клиенте определим следующий код:
В данном случае кроме файла в MultipartFormDataContent добавляется два объекта StringContent, который представляет обычную строку. Ключи обоих объектов соответствуют тем, которые используются для получения данных на сервере — «username» и «email».
В результате выполнения консоль нам выведет:
А на сервере в папке uploads появится еще один файл — logo.jpg.
Источник: metanit.com
Как отправлять и загружать файлы с удаленного сервера в ASP.NET
Данная статья содержит пример framework все-в-одном, который доступен для загрузки. В этом примере кода показано, как отправлять и загружать файлы с локального или удаленного сервера в ASP.NET. Следующие значки загрузки можно загрузить образцы пакетов. C# и Visual Basic .NET версии образца пакета доступны.
В этом примере кода показано, как отправлять и загружать файлы с сервера, который не входит в область запроса пользователя домена. Функциональность доступна для передачи файлов с помощью протоколов HTTP и FTP. Кроме того этот пример кода использует универсальные коды ресурсов (URI) для определения расположения файлов на сервере. Основные классы, используемые в этом примере кода — класс WebClient и класс WebRequest .
Уровень сложности
Информация о скачивании
Чтобы загрузить этот образец кода, щелкните одну из следующих ссылок:
Технический обзор
Это довольно легко отправлять и загружать файлы с удаленного сервера в ASP.NET. Библиотека классов платформа.NET Framework предоставляет объекты упрощенный запрос. Класс WebClient является классом высокого уровня, который облегчает взаимодействие сервера. Класс WebRequest объекты используются с помощью класса WebClient для выполнения запросов.
Классы HttpWebRequest и FtpWebRequest , определенный протокол реализации абстрактного класса WebRequest . HttpWebRequest реализует методы GET и POST протокола HTTP для выгрузки и загрузки файлов. FtpWebRequest реализует методы STOR и RETR протокола FTP для передачи файлов.
Этот пример кода использует методы UploadData и DownloadData класса WebClient для передачи данных из удаленных URI сервера. С помощью метода PUT протокола HTTP используется метод UploadData и «приложения/x-www-формы-urlencoded» Интернет тип носителя. Метод DownloadData используется с помощью объекта FileStream для хранения входной поток данных и запись массива байтов в локальный файл.
Общие сведения о примере
В этом примере кода вы найдете файл RemoteFileForm.aspx, который объясняет, как использовать два новых класса:
- RemoteUpload
- RemoteDownload
Класс RemoteUpload
Класс RemoteUpload имеет два дочерних классов. Эти классы являются HttpRemoteUpload и FtpRemoteUpload. Оба класса с помощью конструктора RemoteUpload . Класс RemoteUpload требует массив байтов данных файлов и URI-адрес сервера. Также можно указать имя, используемое для передаваемого файла. Класс FtpRemoteUpload использует FtpWebRequest напрямую (вместо класс WebClient более высокого уровня) для удовлетворения конкретных требований протокола FTP.
Дополнительные сведения о классе RemoteUpload следующие определения класса см.
public class HttpRemoteUpload : RemoteUpload
public HttpRemoteUpload(byte[] fileData, string fileNamePath, string urlString)
: base(fileData, fileNamePath, urlString)
return true;
>
catch (Exception ex)
throw new Exception(«Failed to upload», ex.InnerException);
>
return true;
>
catch (Exception ex)
throw new Exception(«Failed to upload», ex.InnerException);
>
>
> При нажатии кнопки Отправить в файле RemoteFileForm.cs создается экземпляр объекта RemoteUpload . Передать URI-адрес сервера и путь к локальному файлу физической в качестве параметров для создания объекта.
Примечание. Если не указать имя файла для сохранения файла на сервере, система автоматически создаст имя файла текущей даты и времени на сервере. Дата и время с точностью до миллисекунд. После завершения работы метода UploadData , результат отображается на текущей странице.
Класс RemoteDownload
Класс RemoteDownload также имеет два дочерних классов. Эти классы являются HttpRemoteDownload и FtpRemoteDownload. Класс RemoteDownload требует URI ресурса и локальный физический каталог. Класс RemoteDownload проверяет, чтобы убедиться в том, что URI ресурса существует до загрузки запускается. Класс получает поток, содержащий данные ответа от сервера, а затем записывает байтовый массив FileStream.
Класс FtpRemoteDownload использует FtpWebRequest напрямую (вместо класс WebClient более высокого уровня) для удовлетворения конкретных требований протокола FTP.
Дополнительные сведения о классе RemoteDownload следующие определения класса см.
public class HttpRemoteDownload : RemoteDownload
public HttpRemoteDownload(string urlString, string descFilePath)
: base(urlString, descFilePath)
catch (Exception ex)
throw new Exception(«upload failed», ex.InnerException);
>
>
>
Примечание. Дополнительные сведения о том, как создать и развернуть образец приложения содержатся в файле Readme.txt, входящие в пакет загрузки.
Языки
В этом примере кода доступна на следующих языках программирования:
Источник: support.microsoft.com