I am continuing my exploration of couchapp today by trying to upload attachments to CouchDB documents. I use attachments in my recipe database to include meal and recipe pictures, so I played with them extensively last year (both command line and with Ruby code).
I am not too sure if it is even possible to upload directly from a web form—I believe that only way that this might work is if CouchDB supports POSTs of multipart/form-data to existing documents. CouchDB's HTTP Document API does not mention this, so I am not hopeful.
Before coding, I explore a bit. I'm pretty sure that CouchDB's futon admin interface supports attachment uploads. Maybe I can re-use (or even copy) that. After creating a test document, I notice that there is an "Upload Attachment..." link in futon. Clicking that link I get this dialog:
The form sure acts like an old fashioned document upload, but inspecting the HTML I find:
The form is not multipart/form-data. It does use a normal file
<input>
tag and the button is a <button type="submit">
tag (which submits forms just like an <input type="submit">
tag). That is really weird, I have never seen a file upload without a enc="multipart/form-data"
attribute. Aside from that, this seems pretty solid—the form is being POSTed to the current document, which should push a new thing onto a sub-collection under that document. The _attachments
attribute seems like a perfectly good place for CouchDB to address that.So maybe this will work...
First I create my
shows/upload.js
show function:function(doc, req) {That is very similar to the edit show function that I have used recently, but I take into account that I will need to address the document directly (dbname/docid) in the parameter list.
// !json templates.upload
// !json templates._header
// !json templates._footer
// !code vendor/couchapp/template.js
// !code vendor/couchapp/path.js
return template(templates.upload, {
dbname: 'eee',
docid : doc._id,
rev: doc._rev,
title: doc.title,
asset_path: assetPath(),
header: template(templates._header, {}),
footer: template(templates._footer, {})
});
}
Next I create the template for this show function:
<!DOCTYPE html>No magic in there at all—just like the futon upload I am not specifying multipart/form-data. I am posting directly to the document with only the current document revision number and the uploaded file. Hopefully that will do the trick.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Recipe Image Upload</title>
<link rel="stylesheet" href="<%= asset_path %>/style/main.css" type="text/css" />
</head>
<body>
<%= header %>
<h1>Upload to <%= title %></h1>
<form id="recipe-upload" action="/<%= dbname %>/<%= docid %>" method="post">
<p>
File to attach:
<input type="file" name="_attachments">
</p>
<p>
<button type="submit">Upload</button>
</p>
<input type="hidden" name="_rev" value="<%= rev %>">
</form>
<%= footer %>
</body>
</html>
Unfortunately, when I upload I get this:
{"error":"bad_content_type","reason":"Invalid Content-Type header for form upload"}Dang it.
After some digging, I realize that the "Upload Attachment..." link in futon is not only displaying the form, but also attaching some event listeners. It looks as though some
ajaxSubmit()
fun is in order. I will give that a whirl tomorrow.Day #24
I've just been taking a look at this myself, and the above would have worked had you specified the enctype="multipart/form-data" in your form element!
ReplyDeleteHey Chris, Hey Guy,
ReplyDeletedid you get this to run ? I am pretty confused, searched the almost whole net 'bout "couchdb upload attachment html form" and just found the way you described here. I posted in some forums and didn't get any response.
This is what i did...
http://paste.ubuntu.com/792157/
... and what i got from couchdb...
Fehler 101 (net::ERR_CONNECTION_RESET):
So i hope you can, and of course will, make it some clearer to me.
Thanks in advance, Dennis
@Dennis Been a while since I did this. Newer versions of CouchDB may do it completely differently. But I was able to get it working in a follow-up post the next day: http://japhr.blogspot.com/2010/02/how-to-upload-files-in-couchapp.html
ReplyDelete