Мне нужно загрузить изображения и видеофайлы на сервер в угловом приложении, используя 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 с именем файла promotion.png, поэтому его легко получить, и мы принимаем только видеоформат формата .mp4. Из-за этого нам не нужно беспокоиться о проверке, существует ли файл и нормально ли его перезаписывать. Вот почему вы можете видеть в коде мы удаляем любой существующий файл этого имени перед сохранением.
HTML – это просто ввод с типом файла:
<input type="file" id="img_path" name="img_path" class="promo-img-path" accept="image/*">
Мы используем Angular сейчас, поэтому я не могу просто отправить выше через HTML-форму. Вот что мне нужно выяснить, как это сделать.
Мы – два разработчика, которые делают все возможное, поэтому я уверен, что есть лучший способ сделать это. Однако, прежде чем я реорганизую все это, я надеюсь, что смогу использовать Angular (или jQuery в качестве последнего средства), чтобы просто отправить контроллеру любые данные файла, необходимые Laravel для того, чтобы сделать вышеуказанный код. Ответ может быть таким же простым, как «отправить PUT методу на этом контроллере выше, но вместо обычной полезной нагрузки JSON использовать информацию о файле в этом формате, и вы можете собрать эту информацию с помощью …»
Я также был бы признателен за любые советы по лучшим способам, которые я могу сделать в будущем.
При использовании 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
типа контента application/json
. Установив Content-Type: undefined
, структура AngularJS исключает заголовок типа контента, позволяющий XHR API устанавливать тип содержимого. При отправке объекта FormData API XHR устанавливает тип контента для multipart/form-data
с соответствующими границами и кодировкой base64 .
Для получения дополнительной информации см. Справочник по API-интерфейсу MDN – Метод отправки XHR
Как вы получили информацию о файле в файл
$scope.files
?
Используйте директиву, которая устанавливает переменную области видимости в событии change
.
<input type=file input-files="files" /><br>
Директива о input-files
angular.module("myApp").directive("inputFiles", function($parse) { return function linkFn (scope, elem, attrs) { var inputFilesGetter = $parse(attrs.inputFiles); var inputFilesSetter = inputFilesGetter.assign; elem.on("change", function (e) { inputFilesSetter(scope, e.target.files); scope.$apply(); }); }; });
ДЕМО на PLNKR .