16

AjaxFormファイルのアップロードとアプリエンジンのblobstoreで問題が発生しています。難しさは、blobstoreアップロードハンドラー(blobstore_handlers.BlobstoreUploadHandlerのサブクラス)がコンテンツを返すのではなく、リダイレクト応答を要求するためだと思いますが、よくわかりません。XMLドキュメントを使用できるようにすることを期待しており、ブラウザには期待どおりに到着しているように見えますが、それを把握できません。詳細は以下のとおりです。

私のアプリエンジンのblobstoreアップロードハンドラは次のとおりです-

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')  # 'file' is file upload field in the form
    blob_info = upload_files[0]

    entity_key = self.request.get("entityKey")

    // Update a datastore entity with the blobkey (not shown)

    // redirect to the uri for the updated entity
    self.redirect('%s.xml' % entity_key)

最後のリダイレクトは、xmlドキュメントを返すアプリケーションのURIへのリダイレクトです。サーバーの出力を見ると、何かが間違っているという兆候はありません-リダイレクトが処理され、正しいmimeタイプで期待どおりにxmlドキュメントが返されます-フォームの送信は見栄えがよく、その送信に対するサーバーの応答は次のようになります良い。

ajaxFormを使用したクライアント側のコードは次のようになります(少しわかりにくいですが、問題はここにあるとは思いません)-

// Create the form
var dialogForm = $("<form method='POST' enctype='multipart/form-data'>")
   .append("<span>Upload File: </span><input type='file' name='file'/><br>")
   .append("<input type='hidden' name='entityKey' value='" + entityKey + "'/>")
   .append("<input type='hidden' name='entityField' value='image'/>")
   .append("<input type='button' value='Wait...' disabled='disabled'/>");;

dialogForm.ajaxForm();

// Turn the form button into a nice jQuery UI button and add a click handler
$("input[type=button]", dialogForm[0]).button()
   .click(function() {
      log.info("Posting to : " + dialogForm.attr('action'));
      dialogForm.ajaxSubmit({
         success: function(responseText, statusText, xhr, $form) {
            log.info("Response: " + responseText + ", statusText: " + statusText + ", xhr: " + goog.debug.expose(xhr) + ", form:" + goog.debug.expose($form));
         }
      });
    });

その後、フォームに「アクション」を設定します(そしてボタンを有効にします)-

$.get('/blob_upload_url', function(data) {
  dialogForm.attr("action", data);
  $("input[type=button]", dialogForm[0]).attr("value", "Upload").button("option", "disabled", false);
};

オブジェクトのロギングと公開にも、そこに小さなグーグルクロージャーを使用しています。すべてが良好に見えます-予想どおり、サーバーに正しく投稿され、success関数が呼び出されます。Chrome開発ツールでドキュメントの構造を見ると、ファイルのアップロードと応答を処理するためにiFrameが簡単に作成されていることがわかります。

問題は、応答でxmlドキュメントを取得できないことです。ログ出力は次のとおりです-

[ 18.642s] [Panel] Response: null, statusText: success, xhr: 0 = [object HTMLFormElement]
length = 1
selector = 
jquery = 1.4.2, form:0 = [object HTMLFormElement]
length = 1
selector = 
jquery = 1.4.2
Resource interpreted as document but transferred with MIME type application/xml [ABCdefGH]

mimeタイプに関するchromeの苦情はおそらく非常に関連性がありますが、私は接続を確立していません:)-少なくとも、ある時点でxmlドキュメントを取得していることを意味します。Chromeリソースビューでは、POSTが表示され、応答が302リダイレクトであることがわかります。その後、後続のGETリクエスト(ヘッダーは正常に見えます)が表示されます。

Request URL:http://localhost:8081/_ah/upload/ABCdefGH
Request Method:GET
Status Code:200 OK
Request Headers
Referer:http://localhost:8081/
User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.70 Safari/533.4
Response Headers
Cache-Control:no-cache
Content-Length:2325
Content-Type:application/xml
Date:Sun, 20 Jun 2010 20:47:39 GMT
Expires:Fri, 01 Jan 1990 00:00:00 GMT
Server:Development/1.0

Chromeリソースビューにはそのドキュメントのコンテンツは表示されませんが(空白のみ)、Firefoxには表示され、xmlドキュメントは正常に表示されます。ただし、Firefoxは同じ最終結果を返します-ajaxSubmit()responseTextに対してnull。

ここのどこかで脳が衰えているだけだと思いますが、本当に困惑しています。そのxmlドキュメントを取得するためのポインタは素晴らしいでしょう-乾杯、

コリン

4

3 に答える 3

4

これは、私が使用した方法(Chromeでのみテスト済み)をわずかに変更したものです。AjaxForm ではありませんが、機能します。

function upload_files(entityKey, files, url, progress_callback) {
  var xhr = new XMLHttpRequest(), formData = new FormData();
  xhr.upload['onprogress'] = progress_callback;

  formData.append('entityKey', entityKey);
  $.each(files, function(i, file) { formData.append('file[]', file);});

  xhr.open("post", url, true);
  xhr.setRequestHeader("Cache-Control", "no-cache");
  xhr.send(formData);
}

entityKey、サーバーでパラメーターとして使用できます。'files' パラメータは、file-type 入力フォーム要素の 'files' 属性から取得されます (複数をサポートする配列として)。「progress_callback」パラメーターは、(少なくとも)「loaded」フィールドと「total」フィールド (単位はバイト) を持つオブジェクトを受け取る関数です。サーバーの応答は気にしません。

于 2010-12-02T11:53:45.503 に答える
1

これが私がそれを解決した方法です。ファイルとともに送信するJavaScriptで生成されたランダムなIDを追加しました。アップロードが完了したら、そのランダム ID とアップロードされたファイルの関連付けをしばらく記憶するようにサーバーを構成します。mysite.com/blobdata/that_random_id_i_renerated のような事前定義された URL に別のクエリを送信して、アップロードしたばかりのファイルを要求します。出来た。

于 2011-03-28T12:43:11.650 に答える
0

同じ問題で 5 か月も悩んでいる場合は、ここで質問する必要があると思います。

http://www.google.com/support/forum/p/Chrome/

于 2010-11-24T08:22:47.680 に答える