CouchDB / Cradle如何添加图像?

时间:2011-04-27 04:26:52

标签: node.js couchdb imagesource cradle

所以基本上我想让用户在注册时可以选择上传图像。我不知道从哪里开始永远。我知道CouchDB支持附件,但这与Cradle有什么关系。

我在Cradle的文档中找到了以下代码

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')

但我从哪里去?这一步不会将图像保存在某处的服务器上。那么我是否需要获取图像的地址并将其传递给cradle以将其保存为CouchDB数据库中的附件。

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

3 个答案:

答案 0 :(得分:2)

您需要从表单中获取传入流,然后通过Cradle将数据流发送到CouchDB。

将流发送到Cradle可能很容易。此示例显示如何使用本地文件执行此操作:

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

我认为比较棘手的是管理传入的文件。它们作为多部分流而不是保存到文件中。我倾向于直接或通过formidable间接将代码外包给connect-form,如果您使用的是Connect或Express。

我当前的连接形式代码可归纳为:

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);
            }
        );
    }
});

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

如果您处理图片上传,您应该注意的另一个包是node-imagemagick,,正如您对该名称所期望的那样是ImageMagick的node.js包装。

答案 1 :(得分:1)

仅供参考,对于未来的读者,调用参数自那时起已发生变化,因此这似乎不再有效。检查源代码,因为文档没有描述如何使用它。

答案 2 :(得分:1)

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

附件

Cradle支持编写,阅读和删除附件。读写操作可以是缓冲的,也可以是流式的

编写

您可以缓冲整个附件正文并将其作为单个请求一次性发送。附件上载完成或发生错误后将触发回调函数

<强>语法

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)
})

您可以使用读取流来上传附件正文,而不是先缓冲整个正文。流式上传完成或发生错误后将触发回调函数

<强>语法

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)

当流媒体上传完成后,回调功能将启动

示例 将位于路径'./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)

缓冲

您可以缓冲整个附件并立即接收所有附件。下载完成或发生错误后,将触发回调函数。回调中的第二个参数是附件的二进制数据

<强>语法

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)
})

您也可以流式传输附件。如果附件很大,则流式传输以限制内存消耗会很有用。下载流完成后,将触发回调函数。请注意,只有一个错误参数传递给回调函数。如果下载附件时出错,则错误为null无错误或错误对象。没有第二个参数包含附件数据,如缓冲读取示例

<强>语法

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

示例  假设您要回读使用名称“foo.txt”保存的附件。但是附件foo.txt非常大,所以你想将它流式传输到磁盘而不是将整个文件缓冲到内存中

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)
})