将谷歌关闭拖放文件选择器连接到 Blobstore 图像上传器



我有一个javascript前端连接到Google App Engine后端。将文件上传到 Blobstore 的说明假定您使用的是 JSP,而我不是。创建文件放置处理程序的示例假设您只想在帖子中单独发送文件。

这适用于向上发送文件:

var files = event.getBrowserEvent().dataTransfer.files;
if (files.length > 0) {
  if (files.length > 1) {
    console.log('Too many files!');
  } else {
    var file = files[0];
    var xhr = new goog.net.XmlHttp();
    xhr.open('POST', '/imageUpload?gwt.codesvr=localhost:9997');
    xhr.send(file);
  }
}

但这只是将数据直接发送到我的 servlet。我可以在我的 html 中添加一个表单,但据我所知,闭包不喜欢设置文件类型的输入。

有关如何将文件上传到 Blob 存储的建议?

在这个答案的帮助下,我终于想通了。

首先,确保在您的appengine-web中启用了会话.xml:<sessions-enabled>true</sessions-enabled>

我最终编写了两个单独的 servlet,一个用于创建上传 URL,另一个用于处理图像写入 blobstore 后的重定向。

图片上传网址

public void doGet(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException {
    BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
    Map<String, String> payload = new HashMap<String, String>();
    payload.put("url", blobstoreService.createUploadUrl("/imageUpload"));
    LOGGER.info("Payload: " + GSON.toJson(payload));
    pResponse.setContentType("application/json");
    pResponse.getWriter().println(GSON.toJson(payload));
}

客户端图像上传请求程序

// request function
...
goog.net.XhrIo.send('/imageUploadURL', goog.bind(this.handleURLReceived, this));
...
// response handler function
myapp.ImageDrop.prototype.handleURLReceived = function(event)
{
  this.postURL = this.extractValidJson(event).url;
  myapp.logger.fine('Response: ' + this.postURL);
};

extractValidJson(event)只是我编写的一个实用程序函数,用于提取 json 响应。

一旦我们有了有效的URL,我们就可以允许上传。

客户端上传投递发送程序

// In constructor
...
var dropZone = goog.dom.getElement('image-drop');
var handler = new goog.events.FileDropHandler(dropZone, true);
goog.events.listen(handler, goog.events.FileDropHandler.EventType.DROP, goog.bind(this.handleDrop, this));
...
// FileDropHandler
myapp.ImageDrop.prototype.handleDrop = function(event)
{
  var files = event.getBrowserEvent().dataTransfer.files;
  var file = files[0]; // IRL, do error checking
  this.xhr = new goog.net.XmlHttp();
  this.xhr.open('POST', this.postURL, true); // asych
  this.xhr.onreadystatechange = goog.bind(this.uploadResponseHandler, this);
  var form_data = new FormData();
  form_data.append('file', file); // name is arbitrary, must match in servlet      
  this.xhr.send(form_data);
};

图片上传重定向服务员

public void doPost(HttpServletRequest pRequest, HttpServletResponse pResponse) throws IOException {
    Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(pRequest);
    // 'file' matches param name from form
    for (BlobKey key : blobs.get("file")) {
        LOGGER.info("We have a KEY!!!! " + key);
        blobstoreService.delete(key); // Just testing
    }
    // Make this a real response        
    pResponse.setContentType("text/html");
    pResponse.getWriter().println("OK");

}

然后,您可以在 uploadResponseHandler 中执行任何操作。请求完成是 4(请参阅此处)。

myapp.ImageDrop.prototype.uploadResponseHandler = function(event)
{ 
  if (this.xhr.readyState === myapp.ImageDrop.REQUEST_FINISHED) {
    myapp.logger.fine('Request finished!');
  }
};

一旦所有部分组合在一起,就没那么糟糕了。

最新更新