0

Ich benutze hapijs Version 17.0.1. Ich versuche, ein Bild mit einer Ajax-Anfrage auf einer hapijs-Route hochzuladen. Hier ist meine AJAX-Code Profilbild hochladen:Profilbild hochladen in hapijs 17.0

var image_file_input = document.getElementById("user_profile_upload"); 

image_file_input.onchange = function() { 
    if(this.files != undefined) 
    { 
     if(this.files[0] != undefined) 
     { 
      var formData = tests.formdata ? new FormData() : null; 
      if (tests.formdata) 
      { 
       //alert(file) 
       formData.append('image_file', this.files[0]); 
       formData.append('userId', user_id); 
       formData.append('memberId', member_id); 
      } 
      $.ajax({ 
       url: "/v1/User/uploadUserPic", 
       data: formData, 
       type: "POST", 
       dataType: "json", 
       contentType: false, 
       processData: false, 
       contentType: "multipart/form-data", 
       success: function(data){ 
        console.log(data); 
        var errMsg = null; 
        var resData = null; 
        if(data.statusCode == 200) 
        { 
         resData = data.result; 
        } 
        else 
        { 
         alert(data.message) 
        } 
       }, 
       error: function(error){ 
        alert(error); 
       } 
      }); 
     } 
    } 
} 

Und hier ist mein Hapijs Route Code:

var uploadUserPic = { 
     method: 'POST', 
     path: '/v1/Module/uploadUserPic', 
     config: { 
      description: 'Update Image For User', 
      tags: ['api', 'User'], 
      auth: 'session', 
      payload: { 
       output: 'stream', 
       parse: true, 
       allow: 'multipart/form-data' 
      }, 
      validate: { 
       payload: { 
        userId : Joi.string().regex(/^[a-f\d]{24}$/i).required(), 
        memberId: Joi.string().required(), 
        image_file: Joi.object().required(), 
       }, 
       failAction: FailCallBack 
      } 
     }, 
     handler: function (request, reply) { 
      var resultData = null; 
      var error = null; 
      return new Promise(function (resolve) { 
       var multiparty = require('multiparty'); 
       var fs = require('fs'); 
       var form = new multiparty.Form(); 
       form.parse(request.payload, function (err, fields, files) { 
        if(err) 
        { 
         error = err; 
         resolve(); 
        } 
        else 
        { 
         var mkdirp = require('mkdirp'); 
         var img_dir = "./files/users/"; 
         mkdirp(img_dir, function (err) { 
          if (err) 
          { 
           error = err; 
           console.error(err); 
           resolve(); 
          } 
          else 
          { 
           var oldpath = files.image_file.path; 
           var newpath = "./files/users/"+requestPayload.userId+".png"; 
           fs.rename(oldpath, newpath, function (err) { 
            if(err) 
            { 
             error = err; 
            } 
            resolve(); 
           }); 
          } 
         }); 
        } 
       }); 
      }).then(function (err, result) { 
       if(err) return sendError(err); 
       if(error) return sendError(error) 
       return { 
        "statusCode": 200, 
        "success": true 
       }; 
      }); 
     } 
    } 

Der obige Code gibt mir zu folgen Fehler cannot read property 'content-length' of undefined on line form.parse(request.payload, function (err, fields, files) {});

Bitte lassen Sie mich Wenn ich etwas falsch mache. Wenn ich die URL in Ajax Anfrage durch eine andere URL ersetzen, die ich in PHP geschrieben habe, dann funktioniert es perfekt. was bedeutet, dass etwas mit meinem Code hapijs/nodejs nicht stimmt.

Antwort

0

Es gibt einen guten Beitrag, wie das Hochladen von Dateien in Hapi.js (geschrieben in Version 16) https://scotch.io/bar-talk/handling-file-uploads-with-hapi-js

zu handhaben, da Sie payload.parse = true verwenden, ich bin kein besonderer Grund zu sehen, warum Sie multiparty verwenden. Ich habe den folgenden Arbeits Code, der Dateien (jeglicher Art) von Client in Upload-Verzeichnis hochgeladen speichern würde auf dem Server (Bitte nicht direkt auf die Produktion verwenden, da keine sanitären Einrichtungen durchgeführt wird)

 { 
      path: '/upload', 
      method: 'POST', 
      config: { 
       payload: { 
        output: 'stream', 
        parse: true, 
        allow: 'multipart/form-data' 
       }, 
       validate: { 
        payload: { 
         files: Joi.array().single() 
        } 
       } 
      }, 
      handler: function(request) { 
       const p = request.payload, files = p.files 
       if(files) { 
        console.log(`${files.length} files`) 
        files.forEach(async file => { 
         const filename= file.hapi.filename 
         console.log(`Saving ${filename} to ./uploads`) 
         const out = fs.createWriteStream(`./uploads/${filename}`) 
         await file.pipe(out) 
        }) 
       } 
       return {result: 'ok'} 
      } 
     } 

Sie können die folgenden Befehle verwenden curl-Befehl zum Testen

curl http://localhost:8080/upload -F '[email protected]/path/to/a/note.txt' -F '[email protected]/path/to/test.png' -vvv 

Es gibt ein paar Probleme mit Ihrem Code. Zuerst haben Sie in Ihrem $.ajax Aufruf contentType zweimal angegeben, obwohl es kein Syntaxfehler ist, aber es ist leichtsinnig, so zu codieren. Zweitens ist die Signatur der Funktion in Ihrem .then() Block falsch. Sie mischen die Idee von Promise und Callback. Ich glaube nicht, die folgende Zeile wird

 if(err) return sendError(err); 

Eine letzte triviale Sache ausgelöst werden, Sie sagten, Sie Hapi verwenden 17, sondern auf der Grundlage der Unterschrift-Handler-Funktion

handler: function (request, reply) { 
... 

scheint, Sie sind nicht völlig an Bord mit Hapi17 als die neue Signatur ist

handler: function (request, h) { 

Und es ist nicht nur die Umbenennung von reply-h.

+0

'sendError' formatiert gerade meinen Fehler. zweitens kenne ich sein "h" statt "antworten". aber ich habe von hapi 14 auf 17 upgegraded, also musste ich es im ganzen Projekt ändern. Auch "h" klingt für mich etwas peinlich. Also habe ich "reply" nur als Variablenbezeichnung betrachtet und die Eigenschaften/Funktion von 'h' mit' reply'-Variable aufgerufen. Übrigens Danke für die Hilfe, Kumpel. Ich werde Ihre Lösung überprüfen und auf Sie zurückkommen. –

+0

Es funktionierte wie ein Charme Kumpel. Danke für Ihre Hilfe. Freut mich, deine Antwort zu akzeptieren. –

+0

Kein Problem. Gut zu helfen: D –