2012-04-05 2 views
1

Я пытаюсь загрузить файл из диалогового окна файла HTML5 в свою учетную запись Google Docs.Загрузка файла с содержанием и метаданными в Документы Google возвращает 400 Недопустимый/неверный запрос

Я использую API-интерфейс списка документов Google версии 3.0 для этого запроса и инструкции по ссылке this.

Я собрать правильный возобновляемого создать-Link URL из списка документов JSON после запроса и POST в XML-объект в эту ссылку, чтобы получить местоположения URL. Я получаю ответ 200 OK и URL-адрес местоположения.

После установки заголовков я делаю запрос PUT на URL-адрес местоположения для загрузки файла. Для целей этого вопроса файл меньше 512 КБ, и его не нужно разрывать.

После отправки этого запроса PUT я получаю ответ 400 Bad Request (иногда 400 Invalid Request), и файл не загружается.

Интересно, что если я опускаю заголовок Content-Range, я могу загрузить небольшой файл, но файлы, отличные от текстовых, повреждены.

Я выполнил двоичное сравнение файла, загруженного в память, и локального файла. Кажется, они совпадают.

Чтобы получить доступ к API, я использую Javascript внутри гаджета Google с помощью http://www.google.com/jsapi.

I ПОЛУЧИТЬ, ПОЧТОВАТЬ И ПОЛУЧИТЬ данные, используя gadgets.io.makeRequest. Мой заголовок и токен авторизации кажутся правильными, учитывая, что я могу запросить список документов без проблем.

Какие шаги следует предпринять для решения этой проблемы?

Пример вывода

PUT /feeds/upload/create-session/default/private/full?v=3.0&convert=false&upload_id=[id] 

Host: docs.google.com 
X-Shindig-AuthType: oauth 
Authorization: OAuth oauth_body_hash="x", opensocial_owner_id="x", opensocial_viewer_id="x", opensocial_app_id="x", opensocial_app_url="x", xoauth_signature_publickey="x", xoauth_public_key="x", oauth_version="1.0", oauth_timestamp="x", oauth_nonce="x", opensocial_container="x", oauth_token="x", oauth_consumer_key="x", oauth_signature_method="RSA-SHA1", oauth_signature="x" 
Content-Length: 433 
Content-Range: bytes 0-433/433 
Content-Type: application/x-javascript 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11,gzip(gfe) 
X-Forwarded-For: 74.203.139.139 
X-shindig-dos: on 
X-Upload-Content-Length: 433 
X-Upload-Content-Type: application/x-javascript 

[bytes 0-433] 

==== Received response 1: 
HTTP/1.1 400 



Cache-Control: no-cache, no-store, must-revalidate 

Content-Length: 15 

Content-Type: text/html; charset=UTF-8 

Date: Thu, 05 Apr 2012 19:49:48 GMT 

Expires: Fri, 01 Jan 1990 00:00:00 GMT 

Pragma: no-cache 

Server: HTTP Upload Server Built on Apr 2 2012 11:47:06 (1333392426) 

Via: HTTP/1.1 GWA 

X-Google-Cache-Control: remote-fetch 



Invalid Request 


==== 
    errors: 400 Error 

Редактировать

Двоичный код обработки данных:

// -- File Upload functions -- 
    function constructContent(docTitle) { 
     var atom = ['<?xml version=\"1.0\" encoding=\"UTF-8"?>', 
        '<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:docs=\"http://schemas.google.com/docs/2007\">', 
        '<title>' + docTitle + '</title>', 
        '</entry>'].join(''); 

     return atom;  
    } 

    function writeFile(file, under512) { 
     var body = constructContent(file.name.toString()); 
     var params = {}; 

     console.log(body); 

     params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH; 
     params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "google"; 
     params[gadgets.io.RequestParameters.OAUTH_USE_TOKEN] = "always"; 
     params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST; 
     params[gadgets.io.RequestParameters.POST_DATA] = body; 
     params[gadgets.io.RequestParameters.HEADERS] = { 
      "Content-Type" : "application/atom+xml", 
      "Content-Length" : "359", 
      "X-Upload-Content-Type" : file.type.toString(), 
      "X-Upload-Content-Length" : file.size.toString() 
     }; 

     var data; 
     submitRequest(resumableLink + '&convert=false', params, function(requestSuceeded, data) { 
      if (data.rc == 200) { 
       console.log(data); 
       console.log(data.headers.location[0].toString()); 

       if (under512 == true) { 
        continueFile(data.headers.location[0].toString(), file, ('0-' + file.size + '/' + file.size).toString(), under512, params); 
       } 

       else { 
        continueFile(data.headers.location[0].toString(), file, ('0-524287/' + file.size).toString(), under512, params); 
       } 
      } 
     }); 
    } 

    // recursive 
    function continueFile(location, file, contentRange, under512) { 
     console.log('location: ' + location); 

     var contentLength = "0"; 
     var reader = new FileReader(); 
     var blob; 

     var start = contentRange.split('-')[0].toString(); 
     var stop = contentRange.split('-')[1].split('/')[0].toString(); 

     console.log(file.size); 
     console.log(file.type); 

     console.log('start: ' + start); 
     console.log('stop: ' + stop); 

     console.log(("bytes " + contentRange).toString()); 

     console.log(contentRange); 

     (under512 == true) ? contentLength = contentRange.split('/')[1].toString() : contentLength = "524288"; 
     if (file.webkitSlice) { 
      blob = file.webkitSlice(start, stop+1); 
     } 

     else { 
      blob = file.mozSlice(start, stop+1); 
     } 

     reader.readAsBinaryString(blob); 


     reader.onloadend = function(evt) { 
      if (evt.target.readyState == FileReader.DONE) { 
       console.log(evt.target.result); 

       var b = showResult(reader); 
       // console.log('binary: ' + b); 

       var params = {}; 

       params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH; 
       params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "google"; 
       params[gadgets.io.RequestParameters.OAUTH_USE_TOKEN] = "always"; 
       params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.PUT; 
       params[gadgets.io.RequestParameters.POST_DATA] = evt.target.result; 
       params[gadgets.io.RequestParameters.HEADERS] = { 
        "Content-Length" : (contentLength).toString(), 
        "Content-Type" : file.type.toString(), 
        "Content-Range" : ("bytes " + contentRange).toString().trim() 
        // "GData-Version" : "3.0" 
       }; 


       submitRequest(location.toString().trim(), params, function(requestSucceeded, data) { 
        if (data.rc == 308) { 
         var newStart = start + 524288; 
         var newEnd; 
         (end + 524288 > file.size) ? newEnd = file.size : newEnd = end + 524288; 
         var range = (newStart + '-' + newEnd + '/' + file.size).toString().trim(); 
         continueFile(data.headers.location.toString().trim(), file, range, under512); 
        } 

        else if (data.rc == 201) { 
         console.log('done!'); 
        } 

        else { 
         console.log('terrible error.'); 
         console.log(data); 
         writeObj(data); 
        } 
       }); 
      } 
     }; 


    } 

    function uploadFile() { 
     var file = document.getElementById('uploads').files[0]; 
     var under512 = false; 
     (file.size < 524287) ? under512 = true : under512 = false; 
     writeFile(file, under512); 
    } 
+0

Можете ли вы показать вашу обработку двоичных данных кода? –

+0

Код добавлен. Я использую API файлов HTML5 для получения необработанных данных. –

+0

Вы также можете добавить весь код? –

ответ

0

Как описано в the docs запросы продолжения не имеют X-upload- Content- * заголовки, и должны выглядеть больше:

PUT [next location] 
Content-Length: 524288 
Content-Type: application/pdf 
Content-Range: bytes 0-524287/1073741824 

Кроме того, в журнале 0-433 составляет 434 байт, а не 433.

+0

Удаление заголовков X-Upload-Content- *, похоже, не помогло; Я получаю тот же ответ 400 Bad Request. Однако, спасибо. –

+0

Обновленный ответ, можете ли вы проверить свою длину? –

+0

Просто проверил это. Текстовый файл под 512kb возвратил 308, а файл изображения под 512kb вернул 400. –

Смежные вопросы