AngularJS: মাল্টিপার্ট ফর্ম সহ একটি সহজ ফাইল আপলোড কীভাবে কার্যকর করা যায়?


144

আমি AngularJS থেকে একটি নোড.জেএস সার্ভারে একটি সাধারণ মাল্টিপার্ট ফর্ম পোস্ট করতে চাই, ফর্মটিতে একটি অংশে একটি JSON অবজেক্ট এবং অন্য অংশে একটি চিত্র থাকা উচিত, (আমি বর্তমানে J রিসোর্সের সাহায্যে কেবল JSON অবজেক্টটি পোস্ট করছি)

আমি অনুভব করেছি যে আমার ইনপুট টাইপ = "ফাইল" দিয়ে শুরু করা উচিত, তবে তখন জানতে পেরেছিলাম যে কৌণিক জেএস এর সাথে আবদ্ধ হতে পারে না ..

আমি যে সকল উদাহরণ খুঁজে পাচ্ছি সেগুলি হ'ল টেনে আনার জন্য jQuery প্লাগইনগুলি মোড়ানো। আমি একটি ফাইলের একটি সহজ আপলোড চাই।

আমি অ্যাঙ্গুলারজেএস-এ নতুন এবং নিজের নির্দেশাবলী লেখার ক্ষেত্রে মোটেই স্বাচ্ছন্দ্য বোধ করি না।


1
আমি মনে করি এটি সাহায্য করতে পারে: noypi-linux.blogspot.com/2013/04/…
গিলাস

1
এই উত্তরটি দেখুন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 18571001/… ইতিমধ্যে কর্মক্ষম সিস্টেমের জন্য সেখানে প্রচুর বিকল্প রয়েছে।
অ্যানয়েজ

উত্তর:


188

অ্যাংুলারজ (v.1.0.6 দিয়ে পরীক্ষিত) ব্যতীত অন্য কোনও নির্ভরতার সাথে একটি আসল কার্যক্ষম সমাধান

এইচটিএমএল

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

Angularjs (1.0.6) "ইনপুট-ফাইল" ট্যাগগুলিতে এনজি-মডেল সমর্থন করে না তাই আপনাকে এটি একটি "নেটিভ-ওয়ে" করতে হবে যা ব্যবহারকারীর কাছ থেকে নির্বাচিত সমস্ত ফাইলকে (শেষ পর্যন্ত) পাস করে eventually

নিয়ামক

$scope.uploadFile = function(files) {
    var fd = new FormData();
    //Take the first selected file
    fd.append("file", files[0]);

    $http.post(uploadUrl, fd, {
        withCredentials: true,
        headers: {'Content-Type': undefined },
        transformRequest: angular.identity
    }).success( ...all right!... ).error( ..damn!... );

};

শীতল অংশ অনির্ধারিত সামগ্রী-প্রকার এবং angular.identity: transformRequest যে $ HTTP ডান "সামগ্রী-প্রকার" বেছে নিন ও সীমানা যখন একাধিক তথ্য হ্যান্ডলিং প্রয়োজন পরিচালনের ক্ষমতা প্রদান করে।


2
@ ফ্যাবিও আপনি কি আমাকে ব্যাখ্যা করতে পারবেন যে এই ট্রান্সফর্মআরয়েস্ট কি করে? কৌণিক.নিগ্রহ কি? আমি কেবল মাল্টিপার্ট ফাইল আপলোড সম্পন্ন করার জন্য সারা দিন মাথা ঘুরছিলাম।
agpt

1
একটি জাভা বাকি অ্যাপ্লিকেশনে @RandomUser, যে ভালো কিছু mkyong.com/webservices/jax-rs/file-upload-example-in-jersey
ফ্যাবিও Bonfante

2
বাহ, কেবল উজ্জ্বল, অনেক ধন্যবাদ এখানে আমাকে একাধিক চিত্র এবং কিছু অন্যান্য ডেটা আপলোড করতে হবে যাতে আমি fd.append("file", files[0]); fd.append("file",files[1]); fd.append("name", "MyName")
এফডি

1
কনসোল.লগ (এফডি) ফর্মগুলি ফাঁকা আছে? এটা কি সেভাবে?
জে বোর্নে

4
মনে রাখবেন যে আপনি যদি ডিবাগ ইনফো অক্ষম করে থাকেন তবে এটি কাজ করবে না (প্রস্তাবিত হিসাবে)
ব্রুনো পেরেস

42

আপনি সাধারণ / লাইটওয়েট এনজি-ফাইল-আপলোড নির্দেশিকা ব্যবহার করতে পারেন । এটি ফাইল্যাপ ফ্ল্যাশ শিম সহ নন- এইচটিএমএল 5 ব্রাউজারগুলির জন্য ড্রাগ এবং ড্রপ, ফাইল অগ্রগতি এবং ফাইল আপলোড সমর্থন করে

<div ng-controller="MyCtrl">
  <input type="file" ngf-select="onFileSelect($files)" multiple>
</div>

জাতীয়:

//inject angular file upload directive.
angular.module('myApp', ['ngFileUpload']);

var MyCtrl = [ '$scope', 'Upload', function($scope, Upload) {
  $scope.onFileSelect = function($files) {
  Upload.upload({
    url: 'my/upload/url',
    file: $files,            
  }).progress(function(e) {
  }).then(function(data, status, headers, config) {
    // file is uploaded successfully
    console.log(data);
  }); 

}];

এটি কি প্রতিটি ফাইলের জন্য একবারে একক পোস্টের অনুরোধ সম্পাদন করছে না?
অণয়েজ

হ্যাঁ এটা করে. একের পর এক ফাইল আপলোড করা কেন ভাল, তা নিয়ে গিথুব ইস্যু ট্র্যাকারে আলোচনা রয়েছে। ফ্ল্যাশ এপিআই একসাথে ফাইল প্রেরণকে সমর্থন করে না এবং আফাইক আমাজন এস 3 এটি সমর্থন করে না।
ড্যানিয়েল

সুতরাং, আপনি বলছেন যে সাধারণ আরও সঠিক পদ্ধতিটি একবারে একটি ফাইলের জন্য পোষ্ট অনুরোধ প্রেরণ করছে? আমি এতে বেশ কয়েকটি সুবিধা দেখতে পাচ্ছি, তবে সার্ভার-সাইডের বিশ্রামের সমর্থনটি তৈরি করার সময় আরও বেশি সমস্যা।
অ্যানয়েজ

2
আমি যেভাবে এটি প্রয়োগ করি তা হ'ল প্রতিটি ফাইলকে রিসোর্স সেভ হিসাবে আপলোড করা এবং সার্ভারটি স্থানীয় ফাইল সিস্টেমে (বা ডাটাবেস) সেভ করবে এবং সেই ফাইলটির জন্য একটি অনন্য আইডি (যেমন র্যান্ডম ফোল্ডার / ফাইলের নাম বা ডিবি আইডি) ফিরিয়ে দেবে। তারপরে সমস্ত আপলোড সম্পন্ন হয়ে গেলে, ক্লায়েন্টটি অন্য PUT / POST অনুরোধ প্রেরণ করে যা এই অনুরোধটির জন্য আপলোড করা ফাইলগুলির অতিরিক্ত ডেটা এবং আইডি। তারপরে সার্ভার সম্পর্কিত ফাইলগুলির সাথে রেকর্ডটি সংরক্ষণ করবে। এটি জিমেইলের মতো যখন আপনি ফাইলগুলি আপলোড করেন এবং ইমেল প্রেরণ করেন।
ড্যানিয়েল

1
এটি "সিম্পল / লাইটওয়েট" নয়। স্যাম্পল বিভাগে কেবল একটি ফাইল আপলোড করার উদাহরণ নেই।
ক্রিস

9

সরাসরি ফাইল পাঠানো আরও দক্ষ।

করুন Base64- এনকোডিং এর Content-Type: multipart/form-dataএকটি অতিরিক্ত 33% ওভারহেড যোগ করা হয়েছে। সার্ভার যদি এটি সমর্থন করে তবে সরাসরি ফাইলগুলি প্রেরণ করা আরও দক্ষ is

$scope.upload = function(url, file) {
    var config = { headers: { 'Content-Type': undefined },
                   transformResponse: angular.identity
                 };
    return $http.post(url, file, config);
};

কোনও ফাইল অবজেক্টের সাথে কোনও পোষ্ট পাঠানোর সময় এটি সেট করা গুরুত্বপূর্ণ 'Content-Type': undefinedXHR পাঠান পদ্ধতি তারপর নির্ণয় করতে পারবে ফাইল বস্তুর এবং স্বয়ংক্রিয়ভাবে বিষয়বস্তুর প্রকার সেট।

একাধিক ফাইল প্রেরণ করতে, সরাসরি কোনও ফাইললিস্ট থেকে একাধিক অনুরোধ করা দেখুন$http.post


আমি অনুভব করেছি যে আমার ইনপুট টাইপ = "ফাইল" দিয়ে শুরু করা উচিত, তবে তখন জানতে পেরেছিলাম যে কৌণিক জেএস এর সাথে আবদ্ধ হতে পারে না ..

<input type=file>উপাদান সঙ্গে ডিফল্ট কাজ না NG মডেল নির্দেশ । এটির জন্য একটি কাস্টম নির্দেশিকা প্রয়োজন :

"সিলেক্ট-এনজি-ফাইলস" এর নির্দেশিকা যা 1 এর সাথে কাজ করে Workingng-model

angular.module("app",[]);

angular.module("app").directive("selectNgFiles", 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-ng-files ng-model="fileArray" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileArray">
      {{file.name}}
    </div>
  </body>


$http.post বিষয়বস্তু টাইপ সহ multipart/form-data

যদি অবশ্যই পাঠাতে হয় multipart/form-data:

<form role="form" enctype="multipart/form-data" name="myForm">
    <input type="text"  ng-model="fdata.UserName">
    <input type="text"  ng-model="fdata.FirstName">
    <input type="file"  select-ng-files ng-model="filesArray" multiple>
    <button type="submit" ng-click="upload()">save</button>
</form>
$scope.upload = function() {
    var fd = new FormData();
    fd.append("data", angular.toJson($scope.fdata));
    for (i=0; i<$scope.filesArray.length; i++) {
        fd.append("file"+i, $scope.filesArray[i]);
    };

    var config = { headers: {'Content-Type': undefined},
                   transformRequest: angular.identity
                 }
    return $http.post(url, fd, config);
};

ফর্মডেটা এপিআই সহ কোনও পোষ্ট প্রেরণ করার সময় এটি সেট করা গুরুত্বপূর্ণ 'Content-Type': undefinedXHR পাঠান পদ্ধতি তারপর নির্ণয় করতে পারবে FormDataবস্তু এবং স্বয়ংক্রিয়ভাবে বিষয়বস্তুর প্রকার হেডার সেট একাধিক / ফর্ম-ডেটা সঙ্গে সঠিক সীমানা


filesInputনির্দেশ কৌণিক 1.6.7 সঙ্গে কাজ করছেন বলে মনে হচ্ছে না, আমি ফাইল দেখতে পারবেন না ng-repeatকিন্তু একই $scope.variableনিয়ামক খালি কেন? এছাড়াও আপনার file-modelfiles-input
ড্যান

@ ড্যান আমি এটি পরীক্ষা করেছি এবং এটি কার্যকর হয়। আপনার কোডটিতে আপনার যদি সমস্যা হয় তবে আপনার একটি ন্যূনতম, সম্পূর্ণ, যাচাইযোগ্য উদাহরণ সহ একটি নতুন প্রশ্ন জিজ্ঞাসা করা উচিত । নির্দেশের নামটি পরিবর্তিত হয়েছে select-ng-files। AngularJS 1.7.2 এর সাথে পরীক্ষিত।
জর্জিউগ

5

আমার এই সমস্যাটি ছিল। সুতরাং কয়েকটি পন্থা আছে। প্রথমটি হ'ল নতুন ব্রাউজারগুলি এটিকে সমর্থন করে

var formData = new FormData();

সমর্থন কীভাবে আধুনিক ব্রাউজারগুলিতে সীমাবদ্ধ সে সম্পর্কে তথ্য সহ একটি ব্লগে এই লিঙ্কটি অনুসরণ করুন তবে অন্যথায় এটি পুরোপুরি এই সমস্যার সমাধান করে।

অন্যথায় আপনি টার্গেট অ্যাট্রিবিউটটি ব্যবহার করে একটি আইফ্রেমে ফর্মটি পোস্ট করতে পারেন। আপনি যখন ফর্মটি পোস্ট করবেন তখন কোনও ইফ্র্রেমে লক্ষ্য প্রদর্শন করার বিষয়টি নিশ্চিত করুন যার প্রদর্শন বৈশিষ্ট্যটি কোনওটিতে সেট করা নেই। লক্ষ্যটি ইফ্রেমের নাম। (ঠিক যেমন তুমি জানো.)

আশা করি এটা কাজে লাগবে


আফাইক ফর্মডাটা আইইয়ের সাথে কাজ করে না। ইমেজ ফাইলটির বেস 64 এনকোডিং করা এবং এটি JSON এ প্রেরণ করা আরও ভাল ধারণা? নির্বাচিত ফাইলের পাথ পেতে আমি কীভাবে AngularJS এর ​​সাথে একটি ইনপুট টাইপ = "ফাইল" এ আবদ্ধ করতে পারি?
গাল বেন-হাইম

3

আমি জানি এটি একটি দেরী এন্ট্রি তবে আমি একটি সহজ আপলোডের নির্দেশিকা তৈরি করেছি। যা আপনি কোন সময় কাজ করতে পারেন!

<input type="file" multiple ng-simple-upload web-api-url="/api/post"
       callback-fn="myCallback" />

ওয়েব এপিআই ব্যবহার করে উদাহরণ সহ গিথুবকে আরও সহজ-আপলোড করুন।


2
সত্যি কথা বলতে, আপনার প্রকল্পের রেডমে কপি-পেস্ট কোড করার পরামর্শ দেওয়া একটি বড় কালো চিহ্ন হতে পারে। আপনার প্রকল্পটি এনএমপি বা বোভারের মতো সাধারণ প্যাকেজ পরিচালকদের সাথে সংহত করার চেষ্টা করুন।
স্টেফানো তোরেসি

2

আপনি যেমন $resourceরিসোর্সের বৈশিষ্ট্যগুলিতে প্যারাম বৈশিষ্ট্যে ডেটা নিয়োগ করে আপলোড করতে actionsপারেন:

$scope.uploadFile = function(files) {
    var fdata = new FormData();
    fdata.append("file", files[0]);

    $resource('api/post/:id', { id: "@id" }, {
        postWithFile: {
            method: "POST",
            data: fdata,
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }
        }
    }).postWithFile(fdata).$promise.then(function(response){
         //successful 
    },function(error){
        //error
    });
};

1

আমি মাত্র একটি অ্যাংুলারজেজে সাধারণ আপলোডারের জন্য একটি সহজ নির্দেশিকা (বিদ্যমান একটি পাঠ্যক্রম থেকে) লিখেছি।

(সঠিক jQuery আপলোডার প্লাগইনটি হল https://github.com/blueimp/jQuery-File-Upload )

অ্যাঙ্গুলারজে (সিওআরএস বাস্তবায়ন সহ) ব্যবহার করে একটি সাধারণ আপলোডার

(যদিও সার্ভারের দিকটি পিএইচপি-র জন্য, আপনি এটিকে নোডও পরিবর্তন করতে পারবেন)


1
আপনার রেপোতে ইস্যুতে সাড়া দেওয়া
ওলেগ বেলোসভ

@ ওলেগটিখোনভ: হ্যাঁ, আরও কিছু প্রকল্পের সাথে মারাত্মকভাবে আটকে গেছেন। ফোকাস করতে খুব কমই সক্ষম।
sk8terboi87 ツ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.