所以基本上我想让用户在注册时可以选择上传图片。我永远不知道从哪里开始。我知道CouchDB支持附件,但是它到底是如何在摇篮中工作的呢?
我在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数据库中。
如果你能帮我的话,提前谢谢你!
发布于 2011-05-22 22:07:10
您需要从表单中获取传入的流,然后通过Cradle将流发送到CouchDB。
将流发送到Cradle可能是一件容易的事情。此示例说明如何使用本地文件执行此操作:
db.saveAttachment(
doc.id,
doc.rev,
attachmentId,
mimetype,
fs.createReadStream(path),
function( err, data ){
console.log(data);
}
);在我看来,更棘手的是管理传入的文件。它们以多部分流的形式到达,而不是保存到文件中。我更倾向于将这些代码外包给formidable,如果你使用的是Connect或Express,可以直接外包,也可以通过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包装器。
发布于 2013-03-06 05:38:15
仅供参考,对于将来的读者来说,调用参数从那以后已经改变了,所以这似乎不再有效。检查源代码,因为文档没有描述如何使用它。
发布于 2013-03-21 01:40:51
我在附件上写了一些文档,希望很快就能合并到摇篮自述文件中。现在,这里是相关的部分
附件
Cradle支持写入、读取和删除附件。读取和写入操作可以是缓冲的或流式的
写作
您可以缓冲整个附件正文,并将其作为单个请求一次性发送。该回调函数将在附件上传完成或发生错误后触发
语法
db.saveAttachment(idData, attachmentData, callbackFunction)示例假设您要将文本文档另存为附件,名称为'fooAttachment.txt‘,内容为'Foo document text’
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)流式上传完成后,将触发回调函数
示例将名为'bar.pdf‘的pdf文件附加到现有文档,该文件位于路径'./data/bar.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)Example说您想要读回一个使用名称'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;如果下载附件时出错,则为错误对象。没有包含附件数据的第二个参数,就像buffered read示例中那样
语法
var readStream = db.getAttachment(documentID, attachmentName, callbackFunction)Foo.txt示例说你想要读回一个以‘.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)Example表示您想要删除以名称'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)
})https://stackoverflow.com/questions/5799350
复制相似问题