我想做什么:有一个html表单,里面有文件输入 . 选择文件时,文件输入应上传文件,并获取文件ID,因此在提交表单时,文件ID将与表单一起发布并写入数据库 .
更短版本: I want to store meta data (id for example) with my files.
听起来很简单,但我很难在LoopBack中做到这一点 .
关于这个话题已经进行了几次对话(1,2),似乎都没有找到解决方案,所以我认为这可能是一个一劳永逸的好地方 .
最简单的解决方案是使用模型关系,但LoopBack不支持与文件存储服务的关系 . 凹凸 . 因此,我们必须使用名为 File
的persistedmodel,并覆盖默认的create,delete,以便从我拥有的文件存储模型中保存和删除 - 名为 Storage
.
到目前为止我的设置:
-
我有一个模型/ api / Storage连接到loopback storage service并将文件成功保存到本地文件系统 .
-
我有一个使用文件元数据连接到Mongo的PersistedModel:
name
,size
,url
和objectId
-
我在
create
之前设置了一个远程钩子,因此可以先保存文件,然后将url
注入File.create()
我在那里,根据this LoopBack page,我有ctx应该有文件里面:
File.beforeRemote('create', function(ctx, affectedModelInstance, next) {})`
什么是 ctx
?
ctx.req:Express Request对象 . ctx.result:快速响应对象 .
好的,所以现在我在Express页面上,非常迷失,这就是一个关于'正在解析的中间件'的东西,我不知道它可能是什么 .
我觉得我很接近解决方案, any help would be appreciated . 这种方法对吗?
7 回答
这是使用环回文件存储元数据的完整解决方案 .
你需要一个容器模型
common/models/container.json
在
server/datasources.json
中为容器创建数据源 . 例如:您需要在
server/model-config.json
中将此模型的数据源设置为您拥有的loopback-component-storage
:您还需要一个文件模型来存储元数据并处理容器调用:
common/models/files.json
现在连接
files
与container
:common/models/files.js
为了公开文件api添加到
model-config.json
文件files
模型,请记住选择正确的数据源:Done! 您现在可以在
file
表单字段中使用文件二进制数据调用POST/api/files/upload
. 您将获得返回的id,名称,类型和URL .我有同样的问题 . 我通过创建自己的模型来存储元数据和我自己的上传方法来解决它 .
我创建了一个模型
File
,它将存储名称,类型,网址,userId等信息(与您的相同)我创建了自己的上传远程方法,因为我无法使用钩子 . 容器模型是由loopback-component-storage创建的模型 .
var fileInfo = fileObj.files.myFile[0];
此处myFile是文件上传的字段名称,因此您必须相应地更改它 . 如果您没有指定任何字段,那么它将为fileObj.file.null[0]
. This code lacks proper error checking, do it before deploying it in production .对于那些正在寻找问题答案"how to check file format before uploading a file"的人 .
在这种情况下,我们可以使用可选参数 allowedContentTypes .
我希望它能帮助别人 .
根据您的情况,可能值得考虑使用签名或类似功能,允许直接上传到Amazon S3,TransloadIT(用于图像处理)或类似服务 .
我们对这个概念的第一个决定是,当我们使用GraphQL时,我们希望通过GraphQL避免多部分表单上传,而GraphQL又需要转移到我们后面的Loopback服务 . 此外,我们希望保持这些服务器的有效性,而不会通过(大)上传和相关文件验证和处理来占用资源 .
您的工作流程可能如下所示:
创建数据库记录
返回记录ID和文件上载签名数据(包括S3存储桶或TransloadIT endpoints ,以及任何auth令牌)
客户端上传到 endpoints
对于执行 Banner 广告或头像上传等操作的情况,步骤1已经存在,因此我们跳过该步骤 .
此外,您可以将SNS或SQS通知添加到S3存储桶,以在数据库中确认相关对象现在已附加文件 - 实际上是步骤4 .
这是一个多步骤的过程,但可以很好地消除在核心API中处理文件上载的需要 . 到目前为止从我们最初的实施(在这个项目的早期阶段)开始,用于用户头像和将PDF附加到记录等方面 .
示例参考:
http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html
https://transloadit.com/docs/#authentication
对于那些在POST上遇到 loopback 3 and Postman 问题的人来说,连接挂起(或返回ERR_EMPTY_RESPONSE)(在这里的一些评论中看到)......这个场景中的问题是Postman使用的内容类型"application/x-www-form-urlencoded"!
请删除该 Headers 并添加“Accept”=“multipart / form-data” . 我已经在环回中为此行为提交了一个错误
只需将数据作为
"params"
对象传递,然后在服务器上将其作为ctx.req.query
For example
假设您的存储模型名称为
container
对于AngularJS SDK用户...如果您想使用像Container.upload()这样的生成方法,您可能需要添加一行来配置
lb-services.js
中的方法,以将Content-Type标头设置为undefined
. 这将允许客户端设置Content-Type标头并自动添加边界值 . 看起来像这样: