代码之家  ›  专栏  ›  技术社区  ›  Michael Butler

如何使用XmlHttpRequest 2.0将5 MB文件上载到App Engine BlobStore?

  •  2
  • Michael Butler  · 技术社区  · 16 年前

    我们都知道appengine将大多数输入/输出请求限制为1MB。但是使用最近的blobstoreapi,您可以通过发布到动态生成的URL来完整地上传大型文件。

    根据示例,以下是HTML表单的外观:

    self.response.out.write('<html><body>')
    self.response.out.write('<form action="%s" method="POST" 
      enctype="multipart/form-data">' % upload_url)
      self.response.out.write("""Upload File: 
    <input type="file" name="file"><br> 
    <input type="submit" name="submit" value="Submit"> 
    </form></body></html>""")
    

    但是,我们如何使用HTML5引入的JavaScript技术异步实现这一点呢?这是我到目前为止的一个片段:

    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);
    

    POST 身体。这很好,它不需要BlobStore就可以工作,最多1 MB。在Python中,要读取文件,我只需使用:

    img_data = self.request.body # got my image data now
    

    但是,对于BlobStore,我应该使用

    upload_files = self.get_uploads('file')  # 'file' is file upload field in the form
    

    我的代码未经修改,会导致一个错误

    File "C:\Python26\lib\cgi.py", line 583, in keys
        raise TypeError, "not indexable"
    TypeError: not indexable
    
    2 回复  |  直到 16 年前
        1
  •  3
  •   Nick Johnson    16 年前

    你可能想看看我上传到blobstore的博客文章( 1 , 2 , 3 this recent cookbook post

        2
  •  1
  •   Michael Butler    16 年前

    普遍的共识是,到目前为止,appengine的BlobStore upload API将只接受多部分编码的POST数据。。。换句话说,HTML输入类型=文件形式。或者,您可以使用Firefox通过FileReader API读取用户的二进制文件(通过拖放),并手动重建多部分编码。然后可以使用XmlHttpRequest异步提交数据。

    在撰写本文时,Chrome和Safari不支持FileReader对象,因此它们不能分解二进制文件,因此不能异步发送多部分编码。

    请注意,如果低于1 MB,将文件上载到appengine的drag N drop+XmlHttpRequest方法在上述所有3种浏览器中仍然有效。