Search code examples
pythongoogle-app-enginewebapp2

Handling image upload with BlobstoreUploadHandler and returning a JSON message


I'm trying to upload an image to a URL created with create_upload_url(), handle it with the default BlobstoreUploadHandler and return an JSON message back to the client with the get_serving_url() URL of the image. My code is as follows:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        response = {}

        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]

        response['error'] = False
        response['message'] = "Image uploaded."
        response['image_url'] = images.get_serving_url(blob_info.key())

        self.response.headers['Content-Type'] = 'application/json'
        self.response.out.write(json.dumps(response))

app = webapp2.WSGIApplication(
    [('/_ih/upload_handler/', UploadHandler),
    ], debug=True)

The problem is that no response is received on the client side. The AppEngine logs show a status of 200 on the request. When the request is made with flash, the status code is 200 and no response body, however using HTML5 will output a status of "(cancelled)". I have no idea what is going on. From all the code snippets that I've seen on the internet this should work. Please help! Thank you.


Solution

  • As it turns out, it was an HTML5 Cross-Origin Resource Sharing problem. You can fix this by adding the correct headers on the response:

    class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
        def post(self):
            response = {}
    
            upload_files = self.get_uploads('file')
            blob_info = upload_files[0]
    
            response['error'] = False
            response['message'] = "Image uploaded."
            response['image_url'] = images.get_serving_url(blob_info.key())
    
    
            self.response.headers.add_header("Access-Control-Allow-Methods", "POST") 
            self.response.headers.add_header("Access-Control-Allow-Origin", "*")
    
            self.response.headers['Content-Type'] = 'application/json'
    
            self.response.out.write(json.dumps(response))