CouchDB /摇篮如何添加图像?

所以基本上我想让用户在注册时可以select上传图片。 我不知道从哪里开始永远。 我知道CouchDB支持附件,但Cradle是如何工作的。

我在Cradle的文档中find了下面的代码

saveAttachment: function (/* id, [rev], attachmentName, contentType, dataOrStream */) { 

所以我知道它可以保存附件。 那么我将如何传递图像呢? 我假设在HTML中,我必须使用

 form(action='/upload', enctype='multipart/form-data', method='post') input(type='file', name='upload') input(type='submit', value='Upload') 

但是我从哪里去呢? 这一步不会将图像保存在服务器的某个地方。 然后,我不知何故需要获取图像的地址,并将其传递到摇篮,以将其作为附件保存在CouchDB数据库中。

如果您能帮助我,请提前致谢!

您需要从表单接收stream,然后通过摇篮发送stream到CouchDB。

发送stream到摇篮可能是容易的一点。 这个例子展示了如何用一个本地文件来完成它:

 db.saveAttachment( doc.id, doc.rev, attachmentId, mimetype, fs.createReadStream(path), function( err, data ){ console.log(data); } ); 

在我看来,棘手的一点是pipe理传入的文件。 他们到达作为一个多部分stream而不是被保存到一个文件。 如果您使用的是Connect或Express,我希望将该代码外包给强大的 ,直接或间接通过连接forms 。

我目前的连接forms代码可以总结为:

 req.form.complete(function(err, fields, files){ if ( err ) // handle err else { db.saveAttachment( doc.id, doc.rev, attachmentId, mimetype, fs.createReadStream(files.name), function( err, data ){ console.log(data); } ); } }); 

这对于速度来说并不是最佳的,因为它在磁盘上创build了一个实际的文件,而不是将数据从一个地方传输到另一个地方,但它很方便,可以满足很多用例。

如果你正在处理图像上传,你应该注意的另一个包是node-imagemagick,正如你可能期望的名字是ImageMagick的node.js包装。

仅供参考,对于未来的读者来说,调用参数已经改变,所以这似乎不再有效。 检查源文件没有描述如何使用它。

我写了一些关于附件的文档,希望很快会被合并到摇篮自述中。 现在虽然这里是相关的部分

附件

摇篮支持写入,阅读和删除附件。 读取和写入操作可以是缓冲或stream式传输

写作

您可以缓冲整个附件主体,并将其作为单个请求一次全部发送。 附件上传完成或发生错误后,callback函数将触发

句法

 db.saveAttachment(idData, attachmentData, callbackFunction) 

示例假设您要将文本文档另存为名为“fooAttachment.txt”和内容“Foo文档文本”的附件,

 var doc = <some existing document> var id = doc._id var rev = doc._rev var idAndRevData = { id: id, rev: rev } var attachmentData = { name: 'fooAttachment.txt', 'Content-Type': 'text/plain', body: 'Foo document text' } db.saveAttachment(idAndRevData, attachmentData, function (err, reply) { if (err) { console.dir(err) return } console.dir(reply) }) 

stream

您可以使用读取stream来上传附件主体,而不是先缓冲整个主体。 数据stream上传完成或发生错误后,callback函数将触发

句法

 var doc = savedDoc // <some saved couchdb document which has an attachment> var id = doc._id var rev = doc._rev var idAndRevData = { id: id, rev: rev } var attachmentData = { name: attachmentName // something like 'foo.txt' 'Content-Type': attachmentMimeType // something like 'text/plain', 'application/pdf', etc. body: rawAttachmentBody // something like 'foo document body text' } var readStream = fs.createReadStream('/path/to/file/') var writeStream = db.saveAttachment(idData, attachmentData, callbackFunction) readStream.pipe(writeStream) 

当stream媒体上传完成后,callback函数将会触发

示例将位于path“./data/bar.pdf”的名称为“bar.pdf”的pdf文件附加到现有文档

 var path = require('path') var fs = require('fs') // this document should already be saved in the couchdb database var doc = { _id: 'fooDocumentID', _rev: 'fooDocumentRev' } var idData = { id: doc._id, rev: doc._rev } var filename = 'bar.pdf' // this is the filename that will be used in couchdb. It can be different from your source filename if desired var filePath = path.join(__dirname, 'data', 'bar.pdf') var readStream = fs.createReadStream // note that there is no body field here since we are streaming the upload var attachmentData = { name: 'fooAttachment.txt', 'Content-Type': 'text/plain' } db.saveAttachment(idData, attachmentData, function (err, reply) { if (err) { console.dir(err) return } console.dir(reply) }, readStream) 

缓冲的

您可以缓冲整个附件并一次性接收。 下载完成或发生错误后,callback函数将触发。 callback中的第二个参数将是附件的二进制数据

句法

 db.getAttachment(documentID, attachmentName, callbackFunction) 

示例假设您要读回名称为“foo.txt”的附件,

 var doc = <some saved document that has an attachment with name *foo.txt*> var id = doc._id var attachmentName = 'foo.txt' db.getAttachment(id, attachmentName, function (err, reply) { if (err) { console.dir(err) return } console.dir(reply) }) 

stream

您也可以stream式传输附件。 如果附件很大,则可以通过stream式传输来限制内存消耗。 一旦下载stream完成,callback函数将触发。 请注意,传递给callback函数只有一个错误参数。 如果在下载附件时出现错误,则表示没有发生错误或错误对象。 没有第二个参数包含像缓冲读取示例中的附件数据

句法

 var readStream = db.getAttachment(documentID, attachmentName, callbackFunction) 

示例假设您要读回名称为“foo.txt”的附件。 然而,附件foo.txt非常大,所以你想把它stream到磁盘上,而不是把整个文件缓冲到内存中

 var doc = <some saved document that has an attachment with name *foo.txt*> var id = doc._id var attachmentName = 'foo.txt' var downloadPath = path.join(__dirname, 'foo_download.txt') var writeStream = fs.createWriteStream(downloadPath) var readStream = db.getAttachment('piped-attachment', 'foo.txt', function (err) { // note no second reply paramter if (err) { console.dir(err) return } console.dir('download completed and written to file on disk at path', downloadPath) }) readStream.pipe(writeStream) 

删除

您可以使用_id和附件名称删除上传的附件

句法

 db.removeAttachment(documentID, attachmentName, callbackFunction) 

示例假设您要删除名为“foo.txt”的附件

 var doc = <some saved document that has an attachment with name *foo.txt*> var id = doc._id var attachmentName = 'foo.txt' db.removeAttachment(id, attachmentName, function (err, reply) { if (err) { console.dir(err) return } console.dir(reply) }) 
Interesting Posts