使用Angular中的其他字段发送FormData

pan*_*s72 28 http multipartform-data form-data http-post angularjs

我有一个有两个input text和一个的表格upload.我必须将它发送到服务器,但我有一些问题连接文件与文本.服务器期望这个答案:

"title=first_input" "text=second_input" "file=my_file.pdf"
Run Code Online (Sandbox Code Playgroud)

这是html:

<input type="text" ng-model="title">
<input type="text" ng-model="text">
<input type="file" file-model="myFile"/>
<button ng-click="send()">
Run Code Online (Sandbox Code Playgroud)

这是控制器:

$scope.title = null;
$scope.text = null;

$scope.send = function(){
  var file = $scope.myFile;
  var uploadUrl = 'my_url';
  blockUI.start();
  Add.uploadFileToUrl(file, $scope.newPost.title, $scope.newPost.text, uploadUrl);
};
Run Code Online (Sandbox Code Playgroud)

这是指令 fileModel:

  return {
restrict: 'A',
link: function(scope, element, attrs) {
  var model = $parse(attrs.fileModel);
  var modelSetter = model.assign;

  element.bind('change', function(){
    scope.$apply(function(){
      modelSetter(scope, element[0].files[0]);
    });
  });
}
};
Run Code Online (Sandbox Code Playgroud)

这就是服务,其调用服务器:

  this.uploadFileToUrl = function(file, title, text, uploadUrl){
   var fd = new FormData();
   fd.append('file', file);
   var obj = {
     title: title,
     text: text,
     file: fd
   };
   var newObj = JSON.stringify(obj);

     $http.post(uploadUrl, newObj, {
       transformRequest: angular.identity,
       headers: {'Content-Type': 'multipart/form-data'}
     })
  .success(function(){
    blockUI.stop();
  })
  .error(function(error){
    toaster.pop('error', 'Errore', error);
  });
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试发送,我得到错误400,响应是:Multipart form parse error - Invalid boundary in multipart: None.请求的有效载荷是:{"title":"sadf","text":"sdfsadf","file":{}}

Kyl*_*yle 59

不要FormData使用POST服务器进行序列化.做这个:

this.uploadFileToUrl = function(file, title, text, uploadUrl){
    var payload = new FormData();

    payload.append("title", title);
    payload.append('text', text);
    payload.append('file', file);

    return $http({
        url: uploadUrl,
        method: 'POST',
        data: payload,
        //assign content-type as undefined, the browser
        //will assign the correct boundary for us
        headers: { 'Content-Type': undefined},
        //prevents serializing payload.  don't do it.
        transformRequest: angular.identity
    });
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

MyService.uploadFileToUrl(file, title, text, uploadUrl).then(successCallback).catch(errorCallback);
Run Code Online (Sandbox Code Playgroud)

  • 问题出在你的后端控制器上.不是Javascript. (8认同)

JpG*_*JpG 6

这是完整的解决方案

HTML代码,

创建文本anf文件上传字段,如下所示

    <div class="form-group">
        <div>
            <label for="usr">User Name:</label>
            <input type="text" id="usr" ng-model="model.username">
        </div>
        <div>
            <label for="pwd">Password:</label>
            <input type="password" id="pwd" ng-model="model.password">
        </div><hr>
        <div>
            <div class="col-lg-6">
                <input type="file" file-model="model.somefile"/>
            </div>


        </div>
        <div>
            <label for="dob">Dob:</label>
            <input type="date" id="dob" ng-model="model.dob">
        </div>
        <div>
            <label for="email">Email:</label>
            <input type="email"id="email" ng-model="model.email">
        </div>


        <button type="submit" ng-click="saveData(model)" >Submit</button>
Run Code Online (Sandbox Code Playgroud)

指令代码

创建一个filemodel指令来解析文件

.directive('fileModel', ['$parse', function ($parse) {
return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        var model = $parse(attrs.fileModel);
        var modelSetter = model.assign;

        element.bind('change', function(){
            scope.$apply(function(){
                modelSetter(scope, element[0].files[0]);
            });
        });
    }
};}]);
Run Code Online (Sandbox Code Playgroud)

服务代码

将文件和字段附加到表单数据并执行$ http.post,如下所示,记住保留'Content-Type':undefined

 .service('fileUploadService', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, username, password, dob, email, uploadUrl){
        var myFormData = new FormData();

        myFormData.append('file', file);
        myFormData.append('username', username);
        myFormData.append('password', password);
        myFormData.append('dob', dob);
        myFormData.append('email', email);


        $http.post(uploadUrl, myFormData, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
            .success(function(){

            })
            .error(function(){
            });
    }
}]);
Run Code Online (Sandbox Code Playgroud)

在控制器中

现在在控制器中通过发送要附加在参数中的所需数据来调用服务,

$scope.saveData  = function(model){
    var file = model.myFile;
    var uploadUrl = "/api/createUsers";
    fileUpload.uploadFileToUrl(file, model.username, model.password, model.dob, model.email, uploadUrl);
};
Run Code Online (Sandbox Code Playgroud)