Как загрузить файл 5 МБ в App Engine BlobStore с помощью XmlHttpRequest 2.0? - PullRequest
2 голосов
/ 31 августа 2010

Мы все знаем, что App Engine ограничивает вас 1 МБ для большинства запросов ввода / вывода.Но с недавним API BlobStore вы можете загружать большие файлы в полном объеме посредством POSTing на динамически генерируемый 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>""")

Но как мы можем сделать это асинхронно, используя методы JavaScript, представленные в HTML5?Это фрагмент того, что у меня есть:

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 МБ.В 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

Но я не используюHTML-форма с вводом type = file, я использую XmlHttpRequest - как я могу заставить App Engine «думать», что это файл из HTML-формы, и таким образом «захватывать» данные файла?

Мой код, без изменений, приводит к ошибке

File "C:\Python26\lib\cgi.py", line 583, in keys
    raise TypeError, "not indexable"
TypeError: not indexable

Ответы [ 2 ]

3 голосов
/ 31 августа 2010

Вы можете проверить мои записи в блоге о загрузке в Blobstore ( 1 , 2 , 3 ), а также thisнедавний пост поваренной книги .

1 голос
/ 03 сентября 2010

Общее мнение состоит в том, что пока API загрузки BlobStore App Engine будет принимать только POST-данные, состоящие из нескольких частей ... другими словами, тип ввода HTML = форма файла. Или вы можете использовать Firefox для чтения двоичного файла пользователя (с помощью перетаскивания) с помощью API-интерфейса FileReader и восстановления составной кодировки вручную. Затем вы можете отправить данные асинхронно с помощью XmlHttpRequest.

На момент написания статьи Chrome и Safari не поддерживают объект FileReader, поэтому они не могут разбивать двоичные файлы и, следовательно, не отправлять многочастное кодирование асинхронно.

Обратите внимание, что метод drag N drop + метод XmlHttpRequest для загрузки файлов в App Engine по-прежнему работает во всех трех вышеупомянутых браузерах, если их размер меньше 1 МБ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...