1

HTML5 ファイル ダイアログから Google ドキュメント アカウントにファイルをアップロードしようとしています。

このリクエストには Google Documents List API バージョン 3.0 を使用し、このリンクの手順を使用しています。

クエリの後、Documents List JSON から正しいresumable-create-link URL を収集し、XML エンティティをそのリンクに POST して、場所のURL を取得します。200 OK 応答とロケーション URL を受け取ります。

ヘッダーを設定したら、場所の URL に PUT リクエストを送信してファイルをアップロードします。この質問では、ファイルは 512kb 未満であり、チャンク化する必要はありません。

この PUT リクエストを送信した後、400 Bad Request (場合によっては 400 Invalid Request) 応答を受け取り、ファイルがアップロードされません。

興味深いことに、Content-Rangeヘッダーを省略すると、小さなファイルをアップロードできますが、テキスト ファイル以外のファイルは破損します。

メモリにロードされたファイルとローカル ファイルのバイナリ比較を実行しました。それらが一致しているように見えます。

API にアクセスするために、 http://www.google.com/jsapiを使用して Google Gadget 内で Javascript を使用しています。

gadgets.io.makeRequest を使用してデータを GET、POST、および PUT します。問題なくドキュメントのリストを照会できることを考えると、認証ヘッダーとトークンは正しいようです。

この問題を解決するには、どのような手順を実行する必要がありますか?

サンプル出力

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

1 に答える 1

0

ドキュメントで説明されているように、継続リクエストには X-Upload-Content-* ヘッダーがなく、次のようになります。

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

さらに、ログの 0-433 は 433 ではなく 434 バイトです。

于 2012-04-05T20:57:46.990 に答える