AjaxForm和应用引擎blobstore [英] AjaxForm and app engine blobstore

查看:169
本文介绍了AjaxForm和应用引擎blobstore的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 AjaxForm 文件上传和应用引擎blobstore方面遇到了一些困难。我怀疑是因为blobstore上传处理程序(blobstore_handlers.BlobstoreUploadHandler的子类)强制重定向响应,而不是返回任何内容,但我不确定。我希望得到一个XML文档来处理,它看起来像预期的那样到达浏览器,但我无法控制它 - 下面的细节。



我的app引擎blobstore上传处理程序如下 -

  class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def文件上传字段的格式为
blob_info = upload_files [0]

entity_key = self.request.get(entityKey)

//使用blobkey更新数据存储实体(未显示)

//重定向到uri以获取更新的实体
self.redirect('%s.xml'%entity_key)

最后的重定向是在我的应用程序中返回一个XML文档的URI。查看服务器输出,没有迹象表明任何错误 - 重定向被服务,并且如预期的那样返回xml文档,并具有正确的mime类型 - 所以表单提交看起来很好,服务器对提交的响应看起来像好的。

使用ajaxForm的客户端代码如下所示(对不起,它有一点钝,我不认为问题在这里) -

  //创建表单
var dialogForm = $(< form method ='POST'enctype ='multipart / form-data'> ;)
.append(< span>上传文件:< / 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();

//将表单按钮转换为一个漂亮的jQuery UI按钮,并添加一个单击处理函数
$(input [type = button],dialogForm [0])。 b $ b .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)+ ,形式:+ goog.debug.expose($ form));
}
});
});

我在表单上设置了'action'(并启用了按钮) -


$ b $

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

我在这里使用了一个小的google闭包,以及记录和暴露对象。 - 正如预期的那样,它正确地发布到服务器,并且调用成功函数。如果我在Chrome开发工具中观察文档结构,我可以看到正在创建的iFrame用于处理文件上传和响应。



问题是我从来没有在响应中得到xml文档。日志输出如下 -

  [18.642s] [Panel] Response:null,statusText:success,xhr:0 = [object HTMLFormElement] 
length = 1
selector =
jquery = 1.4.2 ,形式:0 = [对象HTMLFormElement]
长度= 1
选择器=
jquery = 1.4.2
解释为文档但通过MIME类型application / xml传输的资源[ABCdefGH]

关于mime类型的chrome投诉可能与超级相关,但我没有建立连接:) - 至少这意味着它在某些时候正在获取xml文档。在Chrome资源视图中,您可以看到POST,并且响应是302重定向,然后是后续的GET请求 - 其标头看起来很好 -



<$ p $请求URL:http:// localhost:8081 / _ah / upload / ABCdefGH
请求方法:GET
状态码:200 OK
请求标题
Referer:http:// localhost:8081 /
用户代理:Mozilla / 5.0(Macintosh; U; Intel Mac OS X 10_6_4; en-US)AppleWebKit / 533.4(KHTML,如Gecko)Chrome / 5.0。 375.70 Safari / 533.4
响应头文件
Cache-Control:no-cache
Content-Length:2325
Content-Type:application / xml
Date:Sun,20 Jun 2010 20:47:39 GMT
过期时间:1990年1月1日星期五00:00:00 GMT
服务器:开发/ 1.0

Chrome资源视图不会显示该文档的内容(只是空白),但Firefox和xml文档看起来不错。 Firefox给出了相同的最终结果 - 对于ajaxSubmit()responseText为null。



我想我只是在某个地方大脑褪色,但它真的让我难倒。任何获取该xml文档的指针都会很棒 - 欢呼声,



Colin

解决方案

这是我用过的一个方法(只在Chrome中测试过)略有修改。它不是AjaxForm,但它工作。
$ b $ pre $函数upload_files(entityKey,files,url,progress_callback){
var xhr =新的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 是作为服务器上的参数提供。 文件参数来自文件类型输入表单元素的文件属性(作为支持多个数组的数组)。 'progress_callback'参数是一个函数,它接受一个具有(至少)'loaded'和'total'字段(单位是字节)的对象。它不关心服务器响应。


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

解决方案

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.

这篇关于AjaxForm和应用引擎blobstore的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆