title: How do I upload a 5 MB file to App Engine BlobStore using XmlHttpRequest 2.0?
body: <p>We all know that App Engine limits you to 1 MB for most input/output requests. But with the recent BlobStore API, you are allowed to upload large files in full by POSTing to a dynamically generated URL.</p>
  
  <p>According to the sample, here is what the HTML form would look like:</p>
  
  <pre><code>self.response.out.write('&lt;html&gt;&lt;body&gt;')
  self.response.out.write('&lt;form action="%s" method="POST" 
    enctype="multipart/form-data"&gt;' % upload_url)
    self.response.out.write("""Upload File: 
  &lt;input type="file" name="file"&gt;&lt;br&gt; 
  &lt;input type="submit" name="submit" value="Submit"&gt; 
  &lt;/form&gt;&lt;/body&gt;&lt;/html&gt;""")
  </code></pre>
  
  <p>But how can we do this asynchronously using JavaScript techniques introduced with HTML5?  This is a snippet of what I have so far: </p>
  
  <pre><code>xhr.open("POST", post_url); // the post URL given by App Engine
  xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
  xhr.setRequestHeader('Cache-Control', 'no-cache');
  xhr.setRequestHeader('X-File-Name', file.fileName);
  
  // After loading the binary data (last time we only read as base64 string)
  // Tell xhr to start the upload
  myBinaryDataReader.addEventListener("loadend", function(evt){
     xhr.sendAsBinary(evt.target.result);
  }, false);
  
  // Initiate the binary reading on the file, when finished it will 
  // upload asynchronously 
  myBinaryDataReader.readAsBinaryString(file);
  </code></pre>
  
  <p>You'll notice that this technique sends the raw binary file as the <code>POST</code> body. Which is fine, it works without needing the BlobStore for up to 1 MB. In Python, to read the file, I just use:</p>
  
  <pre><code>img_data = self.request.body # got my image data now
  </code></pre>
  
  <p>However, with BlobStore, I'm supposed to use </p>
  
  <pre><code>upload_files = self.get_uploads('file')  # 'file' is file upload field in the form
  </code></pre>
  
  <p><strong>But I'm not using an HTML form with input type=file, I'm using an XmlHttpRequest -- how can I make App Engine "think" it is a file from an HTML form, and thus "grab" the file data?</strong> </p>
  
  <p>My code, unmodified, results in an error   </p>
  
  <pre><code>File "C:\Python26\lib\cgi.py", line 583, in keys
      raise TypeError, "not indexable"
  TypeError: not indexable
  </code></pre>