1

I have a form that allows a user to upload an image to GridFS asynchronously.

I'd like to be able to get the image back from the sever so that I can add it to a div via jQuery.

Previously, in other areas of the app, I've been using getJSON() requests that return content from the server in JSON format with:

Bottle

response.content_type = 'application/json'
return dumps(results)

And then accessing individual fields in jQuery with:

HTML

$("#my_content").append(results.my_db_key)

Is it possible to return an image back in a similarly convenient format that is easy to reference and manipulate in jQuery?

As stated, I'd like to be able to update a div with the retrieved image.

Working Code Below - Just need help with the Bottle part

Form

<form id="ajaxUploadForm" enctype="multipart/form-data" method="post" action="/upload">
<input type="file" id="my_img_upload_input" name="my_image">
<input type="submit" value="upload">
</form>

jQuery

$(document).on("click","#ajaxUploadForm input[type=submit]", function (e) {
e.preventDefault();
var myShinyData = new FormData($("#ajaxUploadForm")[0]);
$.ajax({
url: '/upload',
data: myShinyData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert("This is a success message");
}
});
});

Bottle Route

@route('/upload', method='POST')
def do_upload():
    uploaded_image = request.files.my_image
    name, ext = os.path.splitext(uploaded_image.filename)
    if ext not in ('.png','.jpg','.jpeg'):
        return "File extension not allowed."
    if uploaded_image and uploaded_image.file:
        raw = uploaded_image.file.read()
        filename = uploaded_image.filename
        dbname = 'grid_files'
        db = connection[dbname]
        fs = gridfs.GridFS(db)
        fs.put(raw,filename=filename)
        thing = fs.get_last_version(filename=filename)
        # somehow return the image in a convenient format
        # that can be referenced in jQuery.
        # response.content_type = 'image/jpeg' OR
        # response.content_type = 'application/json' OR
        # something else?  
        # return thing
    return "You missed a field."

Edit:

Here is one solution - using the base64 encoding approach:

dbname = 'grid_files'
db = connection[dbname]
fs = gridfs.GridFS(db)
filename = "my_image.jpg"
my_image_file = fs.get_last_version(filename=filename)
encoded_img_file = base64.b64encode(my_image_file.read())
return encoded_img_file

Accessed on the front end with:

$("#my_img").attr("src", "data:image/png;base64," + data);

from https://stackoverflow.com/a/21213523/1063287

Community
  • 1
  • 1
user1063287
  • 10,265
  • 25
  • 122
  • 218
  • 2
    Add a route for fetching the image and return the appropriate mime type. Then just use that route as the `src` in HTML. Don't use jQuery to fetch the image when the browser can efficiently fetch images. – WiredPrairie Jan 18 '14 at 13:35
  • Interesting idea. The image does not exist on the server until it is uploaded by the user. I could change the image src attr after a successful upload, but this would mean another round trip to the database (via the GET request for the image that would be handled by the route). I am thinking perhaps base64 encode the image retrieved during the first handling, sending it back, and on success adjusting the image src attribute eg ``. Similar to: http://stackoverflow.com/questions/10802312/display-png-image-as-response-to-jquery-ajax-request – user1063287 Jan 18 '14 at 17:30
  • Just respond to the upload with the new ID. That way it could be cached by the browser, and downloaded asynchronously. – WiredPrairie Jan 18 '14 at 17:39
  • Could you explain this a bit more `respond to the upload with the new ID`, I'm having trouble following. – user1063287 Jan 19 '14 at 03:13
  • You should be able to return the path or an id for the uploaded image. – WiredPrairie Jan 19 '14 at 03:35

0 Answers0