AngularJS Загрузить несколько файлов с помощью API FormData

Мне нужно загрузить изображения и видео файлы на сервер в приложении Angular, используя Laravel 5.1 в качестве серверной части. Все запросы Ajax должны сначала отправляться на контроллер Laravel, и у нас есть код для того, как файл обрабатывается, когда он туда попадает. Ранее мы делали обычные HTML-формы для отправки файлов на контроллер, но в этом случае нам нужно избегать обновления страницы формы, поэтому я пытаюсь сделать это в Ajax через Angular.

Какую информацию мне нужно отправить контроллеру Laravel с Ajax, который ранее отправлялся контроллеру через форму HTML?

Это код в контроллере Laravel, который обрабатывал информацию о файле, как только он туда попал. Это то, что мне нужно, чтобы выяснить, как отправить, поэтому я надеюсь, что можно использовать этот код:

    $promotion = Promotion::find($id);
if (Input::hasFile('img_path')){
$path             = public_path().'/images/promotion/'.$id.'/';
$file_path        = $path.'promotion.png';
$delete           = File::delete($file_path);
$file             = Input::file('img_path');
$uploadSuccess    = $file->move($path, 'promotion.png');
$promotion->img_path = '/images/promotion/'.$id.'/promotion.png';
}
if (Input::hasFile('video_path')){
$path             = public_path().'/video/promotion/'.$id.'/';
$file_path        = $path.'promotion.mp4';
$delete           = File::delete($file_path);
$file             = Input::file('video_path');
$uploadSuccess    = $file->move($path, 'promotion.mp4');
$promotion->video_path = '/video/promotion/'.$id.'/promotion.mp4';
}

Как вы можете видеть выше, мы конвертируем любой файл, который мы получаем, в PNG с именем файла promo.png, поэтому его легко получить, и мы принимаем только видео формат .mp4. По этой причине нам не нужно беспокоиться о проверке, существует ли файл, и можно ли его перезаписать. Вот почему вы можете видеть в коде, что мы удаляем любой существующий файл с таким именем перед сохранением.

HTML был просто вводом с типом «file»:

<input type="file" id="img_path" name="img_path" class="promo-img-path" accept="image/*">

Сейчас мы используем Angular, поэтому я не могу больше отправлять вышеупомянутое через форму HTML. Вот что мне нужно выяснить, как это сделать.

Мы два разработчика, которые прилагают все усилия, поэтому я уверен, что есть лучший способ сделать это. Однако, прежде чем я проведу рефакторинг всей этой вещи, я надеюсь, что смогу использовать Angular (или jQuery в качестве крайней меры), чтобы просто отправить контроллеру все данные файла, которые нужны Laravel для работы вышеуказанного кода. Ответ может быть так же прост, как «отправить PUT методу в этом контроллере выше, но вместо обычной полезной нагрузки JSON используйте информацию о файле в этом формате, и вы можете собрать эту информацию с помощью …»

Буду также признателен за любые советы о том, как лучше сделать это в будущем.

2

Решение

Как отправить FormData с помощью службы $ http

При использовании API FormData для POST файлов и данных, важно установить Заголовок Content-Type в undefined,

var fd = new FormData()
for (var i in $scope.files) {
fd.append("fileToUpload", $scope.files[i]);
}
var config = {headers: {'Content-Type': undefined}};

var httpPromise = $http.post(url, fd, config);

По умолчанию среда AngularJS использует тип контента application/json, Установив Content-Type: undefinedплатформа AngularJS опускает заголовок типа контента, позволяющий XHR API установить тип контента. При отправке Объект FormData, API XHR устанавливает тип содержимого multipart/form-data с надлежащими границами и base64 кодирование.

Для получения дополнительной информации см. Справочник по MDN Web API — метод отправки XHR


Как вы получили информацию о файле в $scope.files?

Как включить <input type="file"> работать с ng-model

Эта директива также позволяет <input type="file"> автоматически работать с ng-change а также ng-form директивы.

angular.module("app",[]);

angular.module("app").directive("selectFilesNg", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>

<input type="file" select-files-ng ng-model="fileArray" multiple>

<code><table ng-show="fileArray.length">
<tr><td>Name</td><td>Date</td><td>Size</td><td>Type</td><tr>
<tr ng-repeat="file in fileArray">
<td>{{file.name}}</td>
<td>{{file.lastModified | date  : 'MMMdd,yyyy'}}</td>
<td>{{file.size}}</td>
<td>{{file.type}}</td>
</tr>
</table></code>

</body>
4

Другие решения

Других решений пока нет …