AngularJS 使用 FormData API 上传多个文件 [英] AngularJS Upload Multiple Files with FormData API

查看:35
本文介绍了AngularJS 使用 FormData API 上传多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在使用 Laravel 5.1 作为后端的 Angular 应用程序中将图像和视频文件上传到服务器.所有的 Ajax 请求都需要首先到达 Laravel 控制器,我们在那里有关于文件到达时如何处理的代码.我们之前已经做了普通的 HTML 表单来提交文件上传到控制器,但是在这种情况下我们需要避免表单的页面刷新,所以我通过 Angular 在 Ajax 中尝试这样做.

I need to upload image and video files to the server in an Angular application using Laravel 5.1 as the back end. All Ajax requests need to go to the Laravel controller first, and we have the code there for how the file gets handled when it gets there. We have previously done normal HTML forms to submit file uploads to the controller, but in this case we need to avoid the page refresh of a form, so I am attempting this in Ajax through Angular.

我需要使用 Ajax 将哪些信息发送到 Laravel 控制器,而这些信息以前是通过 HTML 表单发送到控制器的?

What information do I need to send to the Laravel controller with Ajax that was being sent to the controller via an HTML form previously?

这是 Laravel 控制器中的代码,一旦文件信息到达那里,它就会处理文件信息.这就是我需要弄清楚如何发送的,所以我希望可以重用这段代码:

This is the code in the Laravel controller that handled the file information once it got there. That's what I need to figure out how to send, so I can hopefully reuse this code:

    $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 视频格式.因此,我们无需担心检查文件是否存在以及是否可以覆盖它.这就是为什么您可以在代码中看到我们在保存之前删除了该名称的任何现有文件.

As you can see above, we are converting whatever file we get to a PNG with the file name promotion.png so it's easy to fetch, and we are only accepting .mp4 video format. Because of that, we don't need to worry about checking if the file exists and is it ok to overwrite it. That's why you can see in the code we delete any existing file of that name before saving.

HTML 只是一个带有文件"类型的输入:

The HTML was just an input with a type of "file:

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

我们现在正在使用 Angular,所以我不能再通过 HTML 表单发送上述内容了.这就是我需要弄清楚该怎么做.

We are using Angular now so I can't just send the above through an HTML form anymore. That's what I need to figure out how to do.

我们是两个正在竭尽全力的开发人员,所以我相信有更好的方法来做到这一点.然而,在我重构整个事情之前,我希望我可以使用 Angular(或 jQuery 作为最后的手段)将 Laravel 需要的任何文件数据发送给控制器,以使上述代码工作.答案可能很简单,例如向上述控制器中的方法发送 PUT,但不是普通的 JSON 有效负载,而是使用这种格式的文件信息,您可以使用...收集该信息"

We are two developers just doing our best, so I'm sure there is a better way of doing this. However before I refactor this whole thing, I'm hoping I can use Angular (or jQuery as a last resort) to just send the controller whatever file data Laravel needs in order to make the above code work. The answer may be as simple as "send a PUT to the method in that controller above, but instead of a normal JSON payload, use file info in this format and you can gather that info with..."

我也很感激任何有关我将来可以做到这一点的更好方法的提示.

I would also appreciate any tips on better ways I can do this in the future.

推荐答案

如何使用 $http 服务 POST FormData

当使用 FormData API 发布文件和数据,设置 Content-Type 标头很重要undefined.

How to POST FormData Using the $http Service

When using the FormData API to POST files and data, it is important to set the Content-Type header to 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 对象时,XHR API 设置内容输入具有适当边界和 base64multipart/form-data编码.

By default the AngularJS framework uses content type application/json. By setting Content-Type: undefined, the AngularJS framework omits the content type header allowing the XHR API to set the content type. When sending a FormData object, the XHR API sets the content type to multipart/form-data with the proper boundaries and base64 encoding.

有关更多信息,请参阅 MDN Web API 参考 - XHR发送方法

For more information, see MDN Web API Reference - XHR Send method

你是如何将文件信息放入$scope.files的?

How did you get the file information into $scope.files?

如何使ng-model

一起工作

该指令还使 自动与 ng-changeng-form 一起工作> 指令.

How to enable <input type="file"> to work with ng-model

This directive also enables <input type="file"> to automatically work with the ng-change and ng-form directives.

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>

使用 multi-part/form-data 发布二进制文件效率低下,因为 base64 编码 增加了 33% 的额外开销.如果服务器 API 接受带有二进制数据的 POST,则直接发布文件.

Posting binary files with multi-part/form-data is inefficient as the base64 encoding adds an extra 33% overhead. If the server API accepts POSTs with binary data, post the file directly.

请参阅如何发布二进制文件AngularJS(带演示)

这篇关于AngularJS 使用 FormData API 上传多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆