【发布时间】:2014-07-01 07:19:02
【问题描述】:
我最初的问题是特定于 Apps 脚本的,但我发布了一个答案,它可能以更通用的方式有所帮助。
我测试了 HTML 和可以在常规 HTML 中工作的代码,但不适用于 Apps 脚本 HTML 服务。 Apps Script 似乎不会接受来自浏览器的 FILE 对象,而是接受来自浏览器的 FORM 对象。我无法验证这一点,但似乎当使用google.script.run. 将 FORM 对象发送到服务器端.gs 代码时,该代码将从对象中正确提取文件,但如果我发送 INPUT 对象,它不会提取文件。我可能是错的,所以如果有人能明确地告诉我发生了什么,以便其他人阅读这篇文章,那就太好了。
我正在使用文件选择器上传图像文件:
<form class='frmUpload'>
<input name="picOneUpload" onchange="picUpload(this.parentNode)" type="file">
</form>
一旦选择了文件,onchange 事件就会在 <script> 标记中运行 JavaScript picUpload 函数。
<script>
window.picUpload = function(frmData) {
console.log("picUpload ran: " + frmData);
google.script.run.withFailureHandler(onFailure)
.uploadPic(frmData)
};
</script>
console.log 将表单数据显示为[domado object HTMLFormElement FORM]。
然后语句.uploadPic(frmData) 调用服务器端.gs 函数,传递变量frmData。 .gs 代码将对象接收到 arg argBlobInput:
function uploadPic(argBlobInput) {
Logger.log('argBlobInput: ' + argBlobInput);
Logger.log('Keys: ' + Object.keys(argBlobInput));
};
Logger.log 将传入的数据显示为[object Object],而不是[domado object HTMLFormElement FORM]。如果我使用Object.keys(argBlobInput),我会得到输入字段名称的返回值:"picOneUpload"。所以,Object.keys() 在.gs 代码中工作。但是,如果我在前端代码中使用Object.keys(frmData),则不会返回任何键值。我不明白为什么Object.keys() 可以处理传递给后端代码的对象,但不能处理前端代码中的对象?也许与 Caja 有关,因为这是一个 Google Apps 脚本并且 HTML 是用 Caja 清理的?我不知道?但如果这是真的,为什么它会成功地将对象传递给后端代码,并且在那里工作正常?这对我来说毫无意义。
如何从前端的对象[domado object HTMLFormElement FORM] 中获取键值?即使我明确使用输入名称picOneUpload,(在后端代码中显示为对象的键)frmData["picOneUpload"],它也不会返回任何内容。
我想要完成的是在前端设置图像的高度和宽度,然后再将其传递到后端。但是如果我不能使用[domado object HTMLFormElement FORM] 对象,我不知道该怎么做?
如果在该对象上使用 JSONstingify:
console.log("picUpload data: " + JSON.stringify(frmData));
我在控制台中得到的只是:{}
我猜该对象是空的,除了图像 blob。我想我会尝试将文件选择器放在一个没有被 Caja 清理的常规 HTML 文件中,看看会发生什么。
好的,我在不使用 Google Apps 脚本的情况下运行了相同的网页和代码,但遇到了同样的问题。好像有一个object,里面肯定有图片文件,但是object里面没有key?我不明白这一点。图片被传递到服务器,然后服务器将图片上传到我的驱动器,所有这些都没有显示 FORM 对象中有任何内容?
在 Firefox 中,对象被命名为:[object HTMLFormElement]
我需要访问不同于常规对象的 HTMLFormElement 吗?
好吧,我认为这与 Apps 脚本无关。我找到了另一种从文件选择器中检索文件的方法,它返回一个文件对象:[object File]。
我可以得到那个对象的名称和大小。
var fileInput = document.getElementById('picOneUpload');
var file = fileInput.files[0];
console.log("file: " + file.name + "_file size: " + file.size);
哦,我刚刚想出了如何从 FORM 对象中取出 FILE 对象。
console.log("picUpload FILE object: " + frmData.files[0]);
所以,[domado object HTMLFormElement FORM] 里面还有另一个对象,[object File] 对象,但我猜[domado object HTMLFormElement FORM] 对象里面没有键?我可能正在解决这个问题。
我将传递的参数从 this.parentNode 更改为 this,
<input name="picOneUpload" onchange="picUpload(this)">
我更喜欢它,因为我不需要来自所有元素的信息。现在,我没有得到 FORM 对象,而是得到一个 INPUT 对象,我仍然需要从中取出 FILE 对象。
所以有:
- [domado 对象 HTMLFormElement FORM] - 谷歌
- [对象 HTMLFormElement] - Firefox
- [对象 HTMLInputElement]
- [目标文件]
- [对象对象]
我猜有一个标签对象,因为我在表单中有一个标签。我假设 FORM 对象中的数据最多。
使用 Firebug 和 DOM 选项卡,我猜文件有一个属性列表。
- 上次修改日期
- mozFullPath
- 姓名
- 路径
- 尺寸
- 类型
所以,我想这是找出对象中属性名称的一种方法。
传递 this 而不是 this.parentNode 不适用于 Google Apps 脚本 HTML 服务。如果我只是将this 与输入对象一起传递,我会收到一个错误,即零属性为空,或类似的东西。看起来图像变成了 FileUpload 类的一部分。
我找到了显示文件上传的文档: HTML Service Forms File Upload
【问题讨论】:
标签: javascript image forms object google-apps-script