Loopback实现文件上传

3

我使用loopbackjs创建了一个简单的文件上传应用程序。在应用程序的客户端,我使用了简单的HTML和JavaScript代码,并使用AJAX调用调用了loopback api:

$('#upload-input').on('change', function () {

    var files = $(this).get(0).files;

    if (files.length > 0) {
        // One or more files selected, process the file upload
        var form = new FormData();

        for (var index = 0; index < files.length; index++) {

            var file = files[index];
            form.append('Uploded Files', file, file.name);
        }

        $.ajax({
            url: 'api/fileupload/upload',
            type: 'POST',
            data: form,
            processData: false,
            contentType: false,
            success: function (data) {
                console.log('upload successful!');
            }
        });
    }

});

我们在服务器端无法获取文件。在服务器端,我们创建了一个Loopback API,但是如何使用此API上传文件呢?
这是我的Loopback API代码:
FileUpload.remoteMethod

(
        'upload', {
            http: {
                verb: 'post',
            },
            accepts:
            [
                { arg: 'ctx', type: 'object', http: { source: 'context' } },
                { arg: 'options', type: 'object', http: { source: 'query' } }

            ],
            returns: {
                arg: 'data',
                type: 'string',
                root: true
            }
        }
    );

    FileUpload.upload = function (context, options, callback) {
        //context.req.params = 'common';

    };

你有没有检查过LoopBack的存储组件 - http://loopback.io/doc/en/lb3/Storage-component.html? - Aks1357
是的,但我们如何使用它!!请澄清一下。 - Rakesh
谢谢,我们需要将文件存储在服务器端而不是容器中。 - Rakesh
1
容器在服务器端只是文件夹,如果放不下可以提供另一个选项作为答案。 - Aks1357
在服务器端,我们正在使用Loopback API,因此无法获取上传文件的属性。 - Rakesh
显示剩余2条评论
4个回答

8
安装multer: https://github.com/expressjs/multer
npm install --save multer

在MyModel.js中
var multer = require('multer');
var fs = require('fs');

module.exports = function (MyModel) {
    var uploadedFileName = '';
    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            // checking and creating uploads folder where files will be uploaded
            var dirPath = 'client/uploads/'
            if (!fs.existsSync(dirPath)) {
                var dir = fs.mkdirSync(dirPath);
            }
            cb(null, dirPath + '/');
        },
        filename: function (req, file, cb) {
            // file will be accessible in `file` variable
            var ext = file.originalname.substring(file.originalname.lastIndexOf("."));
            var fileName = Date.now() + ext;
            uploadedFileName = fileName;
            cb(null, fileName);
        }
    });


    MyModel.upload = function (req, res, cb) {
        var upload = multer({
            storage: storage
        }).array('file', 12);
        upload(req, res, function (err) {
            if (err) {
                // An error occurred when uploading
                res.json(err);
            } else {
                res.json(uploadedFileName);
            }
        });        
    };

    MyModel.remoteMethod('upload',   {
        accepts: [{
            arg: 'req',
            type: 'object',
            http: {
                source: 'req'
            }
        }, {
            arg: 'res',
            type: 'object',
            http: {
                source: 'res'
            }
        }],
        returns: {
             arg: 'result',
             type: 'string'
        }
    });
};

前端 - 我使用AngularJS,因此请使用以下内容 - https://github.com/nervgh/angular-file-upload

还有其他这样的指令可供使用

P.S. - 根据您的评论 - 实际上我们的问题是,我们需要从客户端上传文件并将该文件存储在数据库中,但在保存到DB之前,我们需要在服务器端获取文件,如果我们通过Post API在服务器端获取文件,则可以轻松地将文件存储在DB中

无法提供确切的解决方案,但使用以上方法,文件将上传到您的/client/uploads文件夹中,上传后,您可以控制对文件进行何种操作,一旦完成所有操作,最终删除它(可选)。


请求POST /api/fileupload/upload的未处理错误:错误:无法在发送后设置标头。 在ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)处。 - Rakesh
我认为出错在这里: res.json(uploadedFileName); - Rakesh
@Santhosh - 在我看到您修改后的代码之前,无法提供适当的解决方案。尝试复制上面的代码并使用多个console.log进行调试,以确定在哪个点获取了值以及它在哪里变为空。 - Aks1357
@Aks1357 我正在调试,以便获得期望值作为 res.end(result)。但是 Postman 的响应只显示 204 No Content。 - Santhosh
@Santhosh,在fs.unlink之前尝试通过console.log(result)进行调试,如果结果被打印出来。或者尝试使用res.send()或res.json()代替res.end()。 - Jayesh_naik
显示剩余7条评论

1
请检查这段代码:
module.exports = function (FileUpload) {
var multer = require('multer');

    FileUpload.remoteMethod(
        'upload', {
            http: {
                verb: 'post',
            },
            accepts:
            [{
                arg: 'req',
                type: 'object',
                http: {
                    source: 'req'
                }
            }, {
                arg: 'res',
                type: 'object',
                http: {
                    source: 'res'
                }
            }],
            returns: {
                arg: 'data',
                type: 'string',
                root: true
            }
        }
    );

    var uploadedFileName = '';

    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            // checking and creating uploads folder where files will be uploaded
            var dirPath = 'client/uploads/'
            if (!fs.existsSync(dirPath)) {
                var dir = fs.mkdirSync(dirPath);
            }
            cb(null, dirPath + '/');
        },
        filename: function (req, file, cb) {
            // file will be accessible in `file` variable
            console.log("----------Second Rakesh---");
            console.log(file);
            var ext = file.originalname.substring(file.originalname.lastIndexOf("."));
            var fileName = Date.now() + ext;
            uploadedFileName = fileName;
            cb(null, fileName);
        }
    });

    FileUpload.upload = function (req, res, callback) {

        var upload = multer({
            storage: storage
        }).array('file', 12);

        upload(req, res, function (err) {
            if (err) {
                // An error occurred when uploading
                res.json(err);
            }
            console.log("-------------Rakesh"); // Its Printing Rakesh

            res.json(uploadedFileName);
        });
    };
};

multer 后添加 var fs = require('fs');,因为我们也在使用它,所以它没有在代码中声明但被使用了,这导致了错误。 - Aks1357
非常感谢,你看到我的代码了吗?你的意思是,在 "var multer = require('multer');" 后面需要添加 "var fs = require('fs');"。 - Rakesh
谢谢,但它显示错误 - 请求POST /api/fileupload/upload的未处理错误:错误:无法在发送后设置标头。并且它也没有打印Console.log(file)。 - Rakesh
谢谢,现在它可以工作了。你能告诉我关于Loopback API的认证和安全性吗?我该如何在我的项目中实现它? - Rakesh
当然,你在用什么,AngularJS吗?以下是一些入门链接 - http://loopback.io/doc/en/lb3/Authentication-authorization-and-permissions.html,http://loopback.io/doc/en/lb3/Create-AngularJS-client.html - Aks1357
显示剩余16条评论

0

你可以使用LoopBack的默认存储组件来上传文件/图片。请前往文档链接,按照说明操作,并特别查看示例项目如何实现文件上传。

你需要为此创建一个数据源和一个容器模型。

创建数据源:

$ lb datasource
[?] Enter the data-source name: myfilesystem
[?] Select the connector for myfilesystem: other
[?] Enter the connector name: loopback-component-storage
[?] Install storage (Y/n)

创建容器模型:
  • 模型名称:Container
  • 数据源:myfilesystem
  • 基类:Model
  • 通过REST API公开评论者?
  • 自定义复数形式(用于构建REST URL):是

0

使用LoopbackJs,这对我很有效。

顺便说一下,Loopback框架是基于ExpressJs的。

您可以将此答案视为https://github.com/blueimp/jQuery-File-Upload/的适用于LoopbackJs的改编版本

安装插件依赖项:

npm install jquery-file-upload-middleware

将以下代码片段添加到您的 /server/server.js 中:
 //Load Jquery File Upload handler
      var upload = require('jquery-file-upload-middleware'),
        bodyParser = require('body-parser');

        // configure upload middleware
        upload.configure({
            uploadDir: __dirname + '/public/uploads',
            uploadUrl: '/uploads',
            imageVersions: {
                thumbnail: {
                    width: 80,
                    height: 80
                }
            }
        });



        app.use('/upload', upload.fileHandler());
        app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))

使用以下代码片段修改middleware.js,以便您的应用程序可以在/client文件夹中提供静态HTML资源(此文件属于LoopbackJs框架):

...
    "files": {
  "loopback#static": {
    "params": "$!../client" 
  }
}
...

下载并放置在/client/test文件上传网页中: 文件上传网页

运行您的node.app并指向http://localhost:3000/files/ 您应该能够上传文件,并在网络选项卡中找到已上传的文件名响应:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接