无法使用Formidable和Request POST到Endpoint

时间:2015-10-29 21:22:28

标签: javascript node.js express formidable node-request

我正在尝试使用Node做一个简单的文件上传到REST端点,但我一直遇到以下错误:

  

TypeError:无法读取属性' hasOwnProperty'为null

我的表格如下:

 <form action="/upload4" method="post" enctype="multipart/form-data">
 <input type="file" name="myfile" />
 <input type="submit" value="Upload" />
 </form>

我在Node / Express中的代码如下:

app.post('/upload4', function (req, res) {
    var form = new formidable.IncomingForm();
    form.parse(req, function (err, fields, files) {
        var options = {
            contentType: files.myfile.type,
            metadata: { fileName: files.myfile.name }
        };
        request.post({ url: 'http://myendpoint.net/uploadPDF', formData: form }, function optionalCallback(err, httpResponse, body) {
            if (err) {
                return console.error('upload failed:', err);
            }
            console.log('Upload successful!  Server responded with:', body);
        });
    console.log(req);
});

我在俯瞰什么。有没有更好的方法通过Node将文件上传到端点?

1 个答案:

答案 0 :(得分:0)

I have solved the issue. I needed to base64 encode the data on the client side before passing it to node to decode to a file. I needed to use XMLHTTPRequest to get binary data properly, as jQuery AJAX appears to have an issue with returning (see here: http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/).

Here is my front end:

var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function (ev) {

 var oData = new FormData(form);

    var xhr = new XMLHttpRequest();
    xhr.responseType = "arraybuffer";

    xhr.open("POST", "http://vendorapi.net/Upload", true);
    xhr.onload = function (oEvent) {
        if (xhr.status == 200) {
            var blob = new Blob([xhr.response], { type: "image/png" });
            //var objectUrl = URL.createObjectURL(blob);
            //window.open(objectUrl);
            console.log(blob);
            var blobToBase64 = function(blob, cb) {
                var reader = new FileReader();
                reader.onload = function() {
                    var dataUrl = reader.result;
                    var base64 = dataUrl.split(',')[1];
                    cb(base64);
                };
                reader.readAsDataURL(blob);
            };

            blobToBase64(blob, function(base64){ // encode
                var update = {'blob': base64};
                var containerName = boxContainerName;
                var filename = 'Texture_0.png';

                $http.post('/postAdvancedTest', { containerName: containerName, filename: filename, file: base64}).success(function (data) {
                    //console.log(data);
                    console.log("success!");

                    // Clear previous 3D render
                    $('#webGL-container').empty();

                    // Generated new 3D render
                    $scope.generate3D();
                }, function (err) {
                    //console.log(err);
                });
            })
        } else {
            oOutput.innerHTML = "Error " + xhr.status + " occurred when trying to upload your file.<br \/>";
        }
    };

    xhr.send(oData);
    ev.preventDefault();
}, false);

Node Backend:

app.post('/postAdvancedTest', function (req, res) {
    var containerName = req.body.containerName
    var filename = req.body.filename;
    var file = req.body.file;
    var buf = new Buffer(file, 'base64'); // decode

    var tmpBasePath = 'upload/'; //this folder is to save files download from vendor URL, and should be created in the root directory previously.
    var tmpFolder = tmpBasePath + containerName + '/';

    // Create unique temp directory to store files
    mkdirp(tmpFolder, function (err) {
        if (err) console.error(err)
        else console.log('Directory Created')
    });

    // This is the location of download files, e.g. 'upload/Texture_0.png'
    var tmpFileSavedLocation = tmpFolder + filename;

    fs.writeFile(tmpFileSavedLocation, buf, function (err) {
        if (err) {
            console.log("err", err);
        } else {
            //return res.json({ 'status': 'success' });
            blobSvc.createBlockBlobFromLocalFile(containerName, filename, tmpFileSavedLocation, function (error, result, response) {
                if (!error) {
                    console.log("Uploaded" + result);

                    res.send(containerName);
                }
                else {
                    console.log(error);
                }
            });
        }
    }) 
})