2015-12-14 9 views
7

मैं मल्टीपार्ट फॉर्म अपलोड से निपटने के लिए अपने नोड एक्सप्रेस सर्वर पर एक POST अनुरोध को संभालने का प्रयास कर रहा हूं, मेरे मामले में उपयोगकर्ता छवियों को अपलोड कर रहा है।पाइप मल्टीपार्ट फॉर्म किसी अन्य सर्वर पर अपलोड करता है

मैं अपने एक्सप्रेस ऐप के माध्यम से अपलोड को अन्य सर्वर पर पाइप करना चाहता हूं जो वर्तमान में बॉडी पार्सर का उपयोग करने के लिए सेटअप है, जिसे मैं भी मल्टीपार्ट बोड्स का समर्थन नहीं करता और इसके बजाय कुछ अन्य पुस्तकालयों का उपयोग करने की सिफारिश करता हूं।

मैंने multiparty देखा है, लेकिन मुझे यकीन है कि यह मेरे क्लाइंट साइड एप्लिकेशन के साथ इसका उपयोग कैसे करें।

मेरे मुवक्किल साइड कोड में मैं बहुत की तरह एक FormData वस्तु पोस्टिंग कर रहा हूँ:

function create(data, name) { 
    var formData = new FormData(); 
    formData.append('file', data, name); 
    return this.parentBase.one('photos').withHttpConfig({transformRequest: angular.identity}).customPOST(formData, undefined, undefined, {'Content-Type': undefined}); 
} 

नोट: मैं से के रूप में दस्तावेज here

तो AngularJS के लिए Restangular पुस्तकालय का उपयोग कर रहा है कि मैं क्या देख समझ बहुपक्षीय दस्तावेज़ों पर, फ़ॉर्म को अपलोड करने के बाद मुझे फॉर्म अपलोड ईवेंट को संभालना होगा और इसे आगे बढ़ाना होगा।

बात यह है कि, मुझे आशा थी कि मैं सीधे अपलोड को किसी अन्य सर्वर पर पाइप कर सकता हूं। पहले से ही मेरा क्लाइंट साइड ऐप इस अन्य सर्वर पर सीधी कॉल कर रहा था, लेकिन अब मैं एक्सप्रेस के माध्यम से सब कुछ प्राप्त करने की कोशिश कर रहा हूं, क्या यह संभव है, या क्या मुझे मल्टीपार्टी की तरह कुछ उपयोग करना है?

अनुरोध प्रलेखन formData का उपयोग करने का एक उदाहरण देता है, लेकिन मुझे यकीन नहीं है कि यह मेरे द्वारा देखे गए बहुपक्षीय उदाहरणों के साथ कैसे काम करेगा। उदाहरण के लिए जब अपलोड मल्टीप्लार्टी का उपयोग करके एक्सप्रेस में पूरा हो जाता है, तो क्या मुझे एक और फॉर्मडेटा ऑब्जेक्ट बनाना होगा, इसके बाद आगे अनुरोध करें, या क्या मुझे प्रत्येक भाग को दूसरे सर्वर पर पाइप करना होगा?

मैं उलझन में हूं, कृपया कोई मेरे लिए इसे साफ़ करने में मदद कर सकता है?

धन्यवाद

संपादित

ठीक है, मैं @yarons टिप्पणियां निम्नलिखित multer पर एक नज़र ले लिया है और यह, कुछ ऐसी बातें मैं का उपयोग किया जा करना चाहते हो रहा है मैं इस का उपयोग करने का प्रयास किया नीचे के अनुसार मेरी एक्सप्रेस रूटर सेटअप के साथ:

routes.js

var express = require('express'), 
    router = express.Router(), 
    customers = require('./customers.controller.js'), 
    multer = require('multer'), 
    upload = multer(); 

router.post('/customers/:customerId/photos/', upload.single('file'), customers.createPhoto); 

controller.js

module.exports.createPhoto = function(req, res) { 
    console.log(req.file); 
    var options = prepareCustomersAPIHeaders(req); 
    options.formData = req.file; 
    request(options).pipe(res); 
}; 

ऊपर नियंत्रक में req.file संपत्ति लॉग आउट हो रहा है कि मैं इस देखें:

{ fieldname: 'file', 
    originalname: '4da2e703044932e33b8ceec711c35582.jpg', 
    encoding: '7bit', 
    mimetype: 'image/png', 
    buffer: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 fa 00 
00 00 fa 08 06 00 00 00 88 ec 5a 3d 00 00 20 00 49 44 41 54 78 5e ac bd f9 8f e 
6 e9 7a ... >, 
    size: 105868 } 

कौन है जो मैं का उपयोग कर ग्राहक के पक्ष कोड से के माध्यम से पोस्ट कर रहा हूँ:

var formData = new FormData(); 
     formData.append('file', data, name); 
     return this.parentBase.one('photos').withHttpConfig({transformRequest: angular.identity}).customPOST(formData, undefined, undefined, {'Content-Type': undefined}); 

क्या मैंने समझदार कोशिश की है? केवल यह काम नहीं करता है, मुझे उस सर्वर से एक त्रुटि मिलती है जिसे मैं पोस्ट करने का प्रयास कर रहा हूं।पहले से जहाँ मैं सर्वर यह सब ठीक काम किया करने के लिए सीधे इस पोस्ट अनुरोध कर रहा था, तो मैं, कुछ मेरी एक्सप्रेस \ Multer सेटअप में गलत

संपादित 2

ठीक होना आवश्यक है ताकि अधिक शिकार के बाद चारों ओर मैं आया this लेख बहुदलीय जो मैं प्रबंधक का उपयोग कर भर में इतनी तरह मेरे सेटअप में काम करने के लिए: मेरे दूसरे सर्वर से अपेक्षा के अनुरूप

var request = require('request'), 
    multiparty = require('multiparty'), 
    FormData = require('form-data'); 

module.exports.createPhoto = function(req, res) { 
    //console.log(req.file); 
    var options = prepareCustomersAPIHeaders(req), 
    form = new multiparty.Form(); 
    options.headers['Transfer-Encoding'] = 'chunked'; 

    form.on('part', function(part){ 
    if(part.filename) { 
     var form = new FormData(), r; 
     form.append(part.name, part, {filename: part.filename, contentType: part['content-type']}); 


     r = request(options, function(err, response, body){ 
     res.status(response.statusCode).send(body); 
     }); 
     r._form = form 
    } 
    }); 

    form.on('error', function(error){ 
    console.log(error); 
    }); 

    form.parse(req); 
}; 

यह अब मेरे लिए फ़ाइलों को अपलोड किया गया है, जबकि इस समाधान काम करता है, मैं लाइन पसंद नहीं :

r._form = form 

अनुरोध वस्तु के लिए एक निजी प्रपत्र चर बताए होने के लिए लगता है, के साथ साथ मैं कुछ भी है कि बहुदलीय पृष्ठों

पर इस तरह से प्रलेखित है

किसी को भी इस संभावित समाधान पर कोई टिप्पणी दे सकते हैं नहीं देख सकते हैं?

+0

आप [multer] की कोशिश की है (https://github.com/expressjs/multer)? यह एक मिडलवेयर है जो आपको अपलोड होने के बाद फ़ाइल तक पहुंचने देता है, और आपको अपलोड घटनाओं को सुनने की आवश्यकता नहीं है – yarons

+0

धन्यवाद @yarons, जो काम करने के लिए एक बहुत ही सरल लाइब्रेरी प्रतीत होता है, मैंने कोड के साथ अपनी पोस्ट संपादित की है मैंने कोशिश की है लेकिन मैं अभी तक यह काम नहीं कर पा रहा हूं। मैं एक्सप्रेस में प्रारंभिक पोस्ट के लिए क्लाइंट में फॉर्मडाटा ऑब्जेक्ट का निर्माण कर रहा हूं, और उम्मीद कर रहा था कि मैं बस उस अनुरोध का उपयोग करता हूं जैसा कि अनुरोध कॉल में फॉर्मडेटा पैरा मान है, मैं अपने अन्य सर्वर को बनाना चाहता हूं। अभी ऐसा लगता है कि मुझे दो फॉर्मडाटा ऑब्जेक्ट्स का उपयोग करना है, जो सही गंध नहीं करता है। – mindparse

+0

[इस उत्तर] में (http://stackoverflow.com/a/30375755/2759075), [सुई] का उपयोग कर एक सर्वर से दूसरे फ़ाइल में फ़ाइल भेजने का एक उदाहरण है (https://github.com/tomas/ सुई) (जो मैंने पहले कभी नहीं की है)। क्षमा करें, मैं सिर्फ आप पर तीसरे पक्ष के पैकेज फेंक रहा हूं ... – yarons

उत्तर

0

हम निम्नलिखित की तरह कुछ का उपयोग करें:

ग्राहक

//HTML 
    <input type="file" ng-file-select uploader="info.uploadPath" /> 


//DIRECTIVES 
    // It is attached to <input type="file" /> element 
    .directive('ngFileSelect', function() { 
    return { 
     link: function($scope, $element) { 
     $element.bind('change', function() { 
      $scope.$emit('file:add', this.files ? this.files : this); 
     }); 
     } 
    }; 
    }) 

//OTHER 
    var uploadPath = '/api/things/' + $stateParams.thingId + '/add_photo' 

    var uploadInfo = { 
       headers: { 
       'Authorization': authToken 
       }, 
       form: { 
       title: scope.info.name 
       } 
      } 


//SERVICE: 
    $rootScope.$on('file:add', function(event, items) { 
    this.addToQueue(items); 
    }.bind(this)); 
    ... 
    addToQueue: function(items) { 
    var length = this.queue.length; 
    angular.forEach(items.length ? items : [items], function(item) { 
     var isValid = !this.filters.length ? true : !!this.filters.filter(function(filter) { 
     return filter.apply(this, [item]); 
     }, this).length; 

     if (isValid) { 
     item = new Item({ 
      url: this.url, 
      alias: this.alias, 
      removeAfterUpload: this.removeAfterUpload, 
      uploader: this, 
      file: item 
     }); 

     this.queue.push(item); 
     } 
    }, this); 

    this.uploadAll(); 
    }, 
    getNotUploadedItems: function() { 
    return this.queue.filter(function(item) { 
     return !item.isUploaded; 
    }); 
    }, 

    /** 
    * Upload a item from the queue 
    * @param {Item|Number} value 
    */ 
    uploadItem: function(value, uploadInfo) { 
    if (this.isUploading) { 
     return; 
    } 

    var index = angular.isObject(value) ? this.getIndexOfItem(value) : value; 
    var item = this.queue[index]; 
    var transport = item.file._form ? '_iframeTransport' : '_xhrTransport'; 
    this.isUploading = true; 
    this[transport](item, uploadInfo); 
    }, 

    uploadAll: function(uploadInfo) { 
    var item = this.getNotUploadedItems()[0]; 
    this._uploadNext = !!item; 
    this._uploadNext && this.uploadItem(item, uploadInfo); 
    }, 

    _xhrTransport: function(item, uploadInfo) { 
    var xhr = new XMLHttpRequest(); 
    var form = new FormData(); 
    var that = this; 

    form.append(item.alias, item.file); 

    angular.forEach(uploadInfo.form, function(value, name) { 
     form.append(name, value); 
    }); 

    xhr.upload.addEventListener('progress', function(event) { 
     var progress = event.lengthComputable ? event.loaded * 100/event.total : 0; 
     that._scope.$emit('in:progress', item, Math.round(progress)); 
    }, false); 

    xhr.addEventListener('load', function() { 
     xhr.status === 200 && that._scope.$emit('in:success', xhr, item); 
     xhr.status !== 200 && that._scope.$emit('in:error', xhr, item); 
     that._scope.$emit('in:complete', xhr, item); 
    }, false); 

    xhr.addEventListener('error', function() { 
     that._scope.$emit('in:error', xhr, item); 
     that._scope.$emit('in:complete', xhr, item); 
    }, false); 

    xhr.addEventListener('abort', function() { 
     that._scope.$emit('in:complete', xhr, item); 
    }, false); 

    this._scope.$emit('beforeupload', item); 

    xhr.open('POST', item.url, true); 

    angular.forEach(uploadInfo.headers, function(value, name) { 
     xhr.setRequestHeader(name, value); 
    }); 

    xhr.send(form); 
    }, 

सर्वर

//things.router 
app.route('/api/things/:thingId/add_photo') 
    .post(things.uploadPhoto); 

//things.controller 
exports.uploadPhoto = function(req, res) { 
    var formidable = require('formidable'); 

    var form = new formidable.IncomingForm(); 

    form.parse(req, function(err, fields, files) { 
    var data = files.qqfile; 
    //actual file is at data.path 
    fs.createReadStream(data.path).pipe(request.put(uploadUrl)); 
    } 
} 
संबंधित मुद्दे