AjaxForm 和应用程序引擎 blobstore

发布于 2024-09-06 08:15:40 字数 3445 浏览 8 评论 0原文

我在 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。查看服务器输出,没有任何迹象表明有任何问题 - 重定向已提供服务,并且它按预期返回 xml 文档,具有正确的 mime 类型 - 因此表单提交看起来不错,并且服务器对该提交的响应看起来不错好的。

我使用 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);
};

我使用了一点谷歌那里也有闭包,用于记录和公开对象。一切看起来都很好 - 正如预期的那样,它正确地发布到服务器,并且成功函数被调用。如果我在 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]

chrome 关于 mime 类型的投诉可能非常相关,但我没有建立连接:) - 至少这意味着它在某个时刻获取了 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() 响应文本为 null。

我想我只是在某个地方大脑衰退了,但这确实让我难住了。任何获取 xml 文档的指示都会很棒 - 干杯,

Colin

I'm having some difficulties with AjaxForm file upload and the app engine blobstore. I suspect the difficulty is because the blobstore upload handler (subclass of blobstore_handlers.BlobstoreUploadHandler) mandates a redirect response, rather than returning any content, but I'm not sure. I'm expecting to get an XML document to work with, and it appears to arrive as expected to the browser, but I just can't get hold of it - details below.

My app engine blobstore upload handler is as follows -

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)

The final redirect is to a uri in my application that returns an xml document. Looking at the server output, there is no indication that anything is wrong - the redirect is serviced, and it returns the xml document as expected, with the correct mime type - so the form submission looks good, and the server response to that submission looks good.

My client side code using ajaxForm looks as follows (sorry its a little obtuse, I dont think the problem is here though)-

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

I set the 'action' on the form (and enable the button) afterwards -

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

I'm using a little google closure in there as well for logging and exposing objects. Everything looks good - as expected it is posting correctly to the server, and the success function is called. If I watch the document structure in Chrome dev tools, I can see the iFrame being created briefly to handle the file upload and response.

The problem is that I never get the xml document in the response. The log output is as follows -

[ 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]

The complaint by chrome about the mime type is probably super relevant, but I'm not making the connection :) - at least it means that it is getting the xml document at some point. In Chrome resources view, you can see the POST, and that the response is a 302 redirect, and then the subsequent GET request - the header of which looks fine -

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 resources view won't show me the content of that document (just blank) but firefox does and the xml document looks fine. Firefox gives the same end result however - null for the ajaxSubmit() responseText.

I figure I'm just having a brain fade here somewhere, but it's really got me stumped. Any pointers for getting that xml document would be great - cheers,

Colin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝情姑娘 2024-09-13 08:15:40

这是我使用过的方法(仅在 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' 参数来自文件类型输入表单元素的 'files' 属性(作为支持多个的数组)。 “progress_callback”参数是一个函数,它接受一个具有(至少)“已加载”和“总计”字段(单位为字节)的对象。它不关心服务器响应。

Here's a method I've used (only tested in Chrome) slightly modified. It's not AjaxForm but it works.

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

The entityKey is available as a param on the server. The 'files' parameter comes from the 'files' attribute of the file-type input form element (as an array to support multiple). The 'progress_callback' parameter is a function that takes an object that has (at least) a 'loaded' and a 'total' field (unit is bytes). It doesn't care about the server response.

永言不败 2024-09-13 08:15:40

这是我解决它的方法。我添加了一个在 javascript 中生成的随机 ID 与文件一起发送。上传完成后,将我的服务器配置为记住该随机 ID 和上传文件的关联一段时间。我向 mysite.com/blobdata/that_random_id_i_renerated 等预定义 URL 发送另一个查询,以请求刚刚上传的文件。它起作用了。

here is how i solved it. I added a random id generatated in javascript send along with file. once the upload complete, configure my server to remember the association of that random id and uploaded file for a while. I send another query to a predefine url like mysite.com/blobdata/that_random_id_i_renerated to request the file just uploaded. it worked.

金橙橙 2024-09-13 08:15:40

如果您在同一问题上遇到了 5 个月的时间。我认为您应该在这里提问:

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

If you are 5 months stuck on the same problem.. I think you should ask here:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文