2015-06-01 18 views
6

tôi vẫn còn lúng túng về phương pháp khác nhau của tải lên tập tin. Máy chủ phụ trợ không nằm trong tầm kiểm soát của tôi nhưng tôi có thể tải lên một tệp bằng cách sử dụng trang Swagger hoặc Postman. Điều đó có nghĩa là máy chủ đang hoạt động OK. Nhưng khi tôi sử dụng AngularJS để tải lên, nó không hoạt động.Tải lên hình nhiều phần dữ liệu dữ liệu với tên tập tin trong Request Payload

Đây là những gì các công trình sử dụng Postman để kiểm tra. Tôi chỉ sử dụng form-data:

enter image description here

ý rằng Yêu cầu Headers có Content-Type là multipart/form-data. Nhưng yêu cầu Payload có filename và Content-Type là hình ảnh/png.

Đây là mã của tôi:

$http({ 
    method: 'POST', 
    url: ApiUrlFull + 'Job/Item?smartTermId=0&name=aaa1&quantity=1&ApiKey=ABC', 
    headers: { 'Content-Type': undefined }, 
    transformRequest: function(data) { 
    var fd = new FormData(); 
    fd.append('file', params.imageData); 
    return fd; 
    } 
}) 

params chỉ là một đối tượng với url tập tin trong imageData.

Mã của tôi cũng có thể gửi params URL tương tự (vì vậy chúng tôi có thể bỏ qua các vấn đề gây ra). Nhưng yêu cầu Payload là base64 và có vẻ khác vì nó thiếu trường filename.

enter image description here

Tôi có zero kiểm soát của backend và nó được viết bằng .NET. Vì vậy, tôi đoán câu hỏi của tôi là: Sử dụng Góc (hoặc $ http hoặc $ tài nguyên), làm cách nào để sửa đổi yêu cầu để tôi gửi đúng Yêu cầu Tải trọng như cách Postman làm điều đó? Tôi không thể tìm ra cách đảo ngược kỹ sư này.

Tôi đã thử https://github.com/danialfarid/ng-file-upload này và nó thực sự đã làm OPTIONS yêu cầu đầu tiên trước khi POST (giả sử vấn đề CORS). Nhưng máy chủ đã đưa ra 405 lỗi cho OPTIONS.

+0

Bạn cần một đối tượng 'File' (hoặc chỉ là một' Blob') thực tế để gửi để nhận được hiệu ứng trong yêu cầu đầu tiên, 'params.imageData' là một chuỗi. – Musa

+0

'params.imageData' chỉ là' tệp: // 'URL từ' kiểu đầu vào = tệp'. Hay bạn có ý gì đó khác mà tôi không nghĩ? –

+0

Từ những gì bạn đăng 'params.imageData' là một png được mã hóa base64, là một chuỗi. Để có được FormData để đăng dữ liệu theo cách bạn muốn nó phải là một đối tượng File hoặc một đối tượng Blob. I'fd.append ('file', blob_from_imageData); 'tìm kiếm SO cho câu hỏi để chuyển đổi một url dữ liệu thành một blob. – Musa

Trả lời

1

Bạn có thể sử dụng một cái gì đó dọc theo dòng:

<input type="file" name="file" onchange="uploadFile(this.files)"/> 

Và trong mã của bạn:

$scope.uploadFile = function(files) { 
    var fd = new FormData(); 
    //Take the first selected file 
    fd.append("file", files[0]); 
    var uploadUrl = ApiUrlFull + 'Job/Item?smartTermId=0&name=aaa1&quantity=1&ApiKey=ABC'; 
    $http.post(uploadUrl, fd, { 
     withCredentials: true, 
     headers: {'Content-Type': undefined }, 
     transformRequest: angular.identity 
    }).success(...all right!...).error(..damn!...); 

}; 
0

nhu cầu của tôi là một sau.

  • Trong biểu mẫu có hình mặc định.
  • Nhấp vào ảnh sẽ mở cửa sổ chọn tệp.
  • Khi người dùng chọn tệp, tệp sẽ được tải ngay lập tức lên máy chủ.
  • Ngay sau khi tôi nhận được phản hồi rằng tệp đó hiển thị hình ảnh hợp lệ cho người dùng thay vì hình mặc định và thêm nút xóa bên cạnh hình ảnh đó.
  • Nếu người dùng nhấp vào ảnh hiện có, cửa sổ chọn tệp sẽ mở lại.

Tôi cố gắng để sử dụng một vài đoạn mã trên github mà không giải quyết được vấn đề, nhưng hướng dẫn tôi một cách đúng đắn, Và những gì tôi đã kết thúc làm là như vậy:

Chỉ

angular.module("App").directive('fileModel', function ($parse) { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      scope.files = {}; 
      var model = $parse(attrs.fileModel); 
      var modelSetter = model.assign; 

      // I wanted it to upload on select of file, and display to the user. 
      element.bind('change', function() { 
       scope.$apply(function() { 
        modelSetter(scope, element[0].files[0]); 
       }); 

       // The function in the controller that uploads the file. 
       scope.uploadFile(); 
      }); 
     } 
    }; 
}); 

Html

<div class="form-group form-md-line-input"> 
    <!-- A remove button after file has been selected --> 
    <span class="icon-close pull-right" 
      ng-if="settings.profile_picture" 
      ng-click="settings.profile_picture = null"></span> 
    <!-- Show the picture on the scope or a default picture --> 
    <label for="file-pic"> 
     <img ng-src="{{ settings.profile_picture || DefaultPic }}" 
      class="clickable" width="100%"> 
    </label> 

    <!-- The actual form field for the file --> 
    <input id="file-pic" type="file" file-model="files.pic" style="display: none;" /> 
</div> 

khiển

$scope.DefaultPic = '/default.png'; 

$scope.uploadFile = function (event) { 
     var filename = 'myPic'; 
     var file = $scope.files.pic; 
     var uploadUrl = "/fileUpload"; 

     file('upfile.php', file, filename).then(function (newfile) { 
      $scope.settings.profile_picture = newfile.Results; 
      $scope.files = {}; 
     }); 
}; 

function file(q, file, fileName) { 
    var fd = new FormData(); 
    fd.append('fileToUpload', file); 
    fd.append('fn', fileName); 
    fd.append('submit', 'ok'); 

    return $http.post(serviceBase + q, fd, { 
     transformRequest: angular.identity, 
     headers: { 'Content-Type': undefined } 
    }).then(function (results) { 
     return results.data; 
    }); 
} 

Hy vọng nó giúp.

P.S. Rất nhiều đoạn mã được lấy từ ví dụ này, nếu bạn cần làm rõ chỉ là bình luận.

Các vấn đề liên quan