通过 AngularJS 将多个文件上传到 Laravel 控制器

Posted

技术标签:

【中文标题】通过 AngularJS 将多个文件上传到 Laravel 控制器【英文标题】:Upload multiple files via AngularJS to Laravel Controller 【发布时间】:2017-08-16 07:31:31 【问题描述】:

我有

浏览文件按钮

<input type="file" upload-files multiple />

创建按钮

<button class="btn btn-link" ng-click="store()" >Create</button>

指令

myApp.directive('uploadFiles', function () 
    return 
        scope: true,
        link: function (scope, element, attrs) 
            element.bind('change', function (event) 
                var files = event.target.files;
                for (var i = 0; i < files.length; i++) 
                    scope.$emit("seletedFile",  file: files[i] );
                
            );
        
    ;
);

监听所选文件

$scope.files = [];
$scope.$on("seletedFile", function (event, args) 

    console.log("event is ", event);
    console.log("args is ", args);

    $scope.$apply(function () 
        $scope.files.push(args.file);
    );

);

发布数据和选定的文件。

$scope.store = function() 

    $scope.model = 
      name: $scope.name,
      type: $scope.type
    ;

    $http(
        method: 'POST',
        url: '/image/store',
        headers:  'Content-Type': undefined ,
        transformRequest: function (data) 
            console.log("data coming into the transform is ", data);
            var formData = new FormData();
            formData.append("model", angular.toJson(data.model));
            for (var i = 0; i < data.files; i++) 
                formData.append("file" + i, data.files[i]);
            
            return formData;
        ,

        data:  model: $scope.model, files: $scope.files 

    )


    .then(function successCallback(response) 
        console.log("%cSuccess!", "color: green;");
        console.log(response);
        $scope.refresh();
        $scope.showModal = false;
        , function errorCallback(response) 
        console.log("%cError", "color: red;");
        console.log(response);
    );
;

结果

在我的控制台中,我没有看到我的文件被传递到后端的控制器。

array:1 [
  "model" => ""type":"wedding""
]

问题

我忘记了哪些步骤?

如何进一步调试?


【问题讨论】:

暂时,当然可以使用github.com/danialfarid/ng-file-upload 【参考方案1】:

我做过几个 angular 1 项目,也发现通过 $http api 上传文件并不简单。希望下面我在项目中使用的代码 sn-p 可以帮助你。

$scope.store = function() 
  var formData = new FormData();

  // add normal properties, the name should be the same as
  // what you would use in a html form
  formData.append('model[name]', $scope.name);
  formData.append('model[type]', $scope.type);

  // add files to form data.
  for (var i = 0; i < $scope.files; i++) 
    formData.append('file' + i, $scope.files[i]);
  

  // Don't forget the config object below
  $http.post('/image/store', formData, 
    transformRequest: angular.identity,
    headers: 'Content-Type': undefined
  ).then(function() 
    // ...
  );
;

【讨论】:

【参考方案2】:

这里给你一些建议:

    Content-type 设置为multipart/form-data 以将内容类型设置为...。“其中包含某些部分,请确保正确获取”。 使用 Axios。这是一个工作示例(如果您没有使用 Axios,这个示例也很好)。 Example to Axios on Uploading File。

【讨论】:

我更新了我的headers: 'Content-Type': undefined , --> headers: 'Content-Type': 'multipart/form-data' , - 仍然没有工作。 我们也可以看看你的 php 脚本吗?【参考方案3】:

您可以使用 FormData 代替

var formData = new FormData();

  formData.append('model[var]', $scope.var);

  // For add to the FormData other file
  for (var i = 0; i < $scope.files; i++) 
    formData.append('file' + i, $scope.files[i]);
  

 // POST REQUEST MUST BE:
  $http.post('url', formData, 
    transformRequest: angular.identity,  //It is for allowing files
    headers: 'Content-Type': undefined
    ).then(function(response) 
  
    // verify if response get 200
  );

【讨论】:

【参考方案4】:

我在 Angular 方面不是很有经验,所以我假设您的前端可以正常工作。

调试提示创建一个名为...我不知道...file_dump.php的 PHP 文件。在该文件中,输入以下代码:

<?php
    echo "<pre>"
    print_r($_REQUEST)
    echo "</pre>"
?>

并提交您的表单。这将显示您的所有请求数据。如果您没有在输出中看到您的文件,则说明您的 javascript 有问题。由于我不擅长 Angular,我将向您指出此链接:link to multiple file upload tutorial using Angular。 这些家伙似乎知道他们在做什么。

如果你确实在 file_dump.php 输出中看到了你的文件,那是你的后端有问题 - Laravel。这一点,我可以帮助你,但我需要查看你的脚本才能在这方面有所帮助。

请务必发布 file_dump.php 的结果。

另外,您是否使用了正确的方法来获取文件? Link。如果没有,那么我们找到了罪魁祸首……

=D 普拉纳夫

【讨论】:

【参考方案5】:

这是我的指令:

app.directive('fileModel', ['$parse', 'message', function ($parse, message) 
    return 
        restrict: 'A',
        link: function (scope, element, attrs) 

            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            //This part is for validate file type in current case must be image
            element.bind('change', function (e) 
                if (attrs.onlyImages == 'true') 
                    if (element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.jpg'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.jpeg'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.png'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.gif'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.bmp'
                    ) 
                        message.error("This field only accept files of type images(jpg,png)");
                        element.attr('is_valid', false);
                        return false;
                     else 
                        element.attr('is_valid', true);
                    
                
                scope.$apply(function () 
                    modelSetter(scope, element[0].files[0]);
                );
            );
        
    ;
]);

html:

<input type="file" only-images="true" file-model="data.image" >

和Js Controller片段:

 var fd = new FormData();
 fd.append('fileImage', data.image);

 $http.post('http://url.com', fd, 
                transformRequest: angular.identity,
                headers: 'Content-Type': undefined,
            )

在 laravel 上获取和复制图像:在文档上很清楚

https://laravel.com/docs/5.4/requests#files

【讨论】:

以上是关于通过 AngularJS 将多个文件上传到 Laravel 控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AngularJS 将文件上传到 Google Drive

通过 angularjs 将图像上传到 cloudinary 时遇到问题

如何从 angularjs 和 CORS 支持将文件上传到球衣

从多个文件上传 Firebase 存储中获取下载 url

我无法通过批处理脚本将多个文件上传到FTP

如何使用 Azure App 服务部署任务通过 VSTS 将多个 jar 文件上传到 Azure