【问题标题】:CouchDB/Cradle How do I add images?CouchDB/Cradle 如何添加图像?
【发布时间】:2011-04-27 04:26:51
【问题描述】:

所以基本上我想让用户在注册时可以选择上传图片。我不知道从哪里开始永远。我知道 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 数据库中。

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

【问题讨论】:

    标签: node.js couchdb imagesource cradle


    【解决方案1】:

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

    将流发送到 Cradle 可能比较简单。这个例子展示了如何使用本地文件:

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

    在我看来,更棘手的一点是管理传入的文件。它们以多部分流的形式到达,而不是保存到文件中。如果您使用 Connect 或 Express,我的偏好是将代码直接外包给 formidable,或者通过 connect-form 间接外包。

    我当前的连接表单代码可以总结为:

    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 包装器。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        附件

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多