我原来的问题是针对Apps脚本的,但我发布的答案可能会以更通用的方式提供帮助。
我测试过的HTML和代码在常规HTML中运行,但不适用于Apps脚本HTML服务。 Apps脚本似乎不会从浏览器接受FILE对象,但是从浏览器接受 FORM 对象。我无法验证这一点,但似乎当一个FORM对象被.gs
发送到服务器端google.script.run.
代码时,代码将正确地从对象中提取文件,但是如果我发送了一个INPUT对象,它不会提取文件。我可能错了,所以如果有人能够明确告诉我发生了什么事,为了其他人阅读它会很好。
我使用文件选择器上传图像文件:
<form class='frmUpload'>
<input name="picOneUpload" onchange="picUpload(this.parentNode)" type="file">
</form>
选择文件后,onchange
事件会在picUpload
代码中运行JavaScript <script>
功能。
<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脚本,并且使用Caja对HTML进行了清理?我不知道?但如果这是真的,为什么它会成功地将对象传递给后端代码,并且它可以正常工作?这对我来说毫无意义。
如何从前端的对象[domado object HTMLFormElement FORM]
中获取键值?即使我明确地使用输入名称picOneUpload
(它显示为后端代码中对象的键)frmData["picOneUpload"]
,它也不返回任何内容。
我想要完成的是在前端传递到后端之前设置前端图像的高度和宽度。但如果我无法使用[domado object HTMLFormElement FORM]
对象,我就不知道我将如何做到这一点?
如果在该对象上使用JSONstingify:
console.log("picUpload data: " + JSON.stringify(frmData));
我进入控制台的所有内容都是:{}
我猜测对象是空的,除了图像blob。我想我会尝试将文件选择器放在一个普通的HTML文件中,该文件没有被Caja消毒,看看会发生什么。
好的,我在不使用Google Apps脚本的情况下运行了相同的网页和代码,我也遇到了同样的问题。似乎有一个对象,它必须有一个图像文件,但对象中没有键?我不明白这一点。图像传递到服务器,然后服务器将图片上传到我的驱动器,所有这些都没有显示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]
对象中没有键我猜?我可能正在努力解决这个问题。
我将arg从this.parentNode
更改为this
,
<input name="picOneUpload" onchange="picUpload(this)">
我更喜欢,因为我不需要所有元素的信息。现在,我得到一个INPUT对象,而不是获取FORM对象,我仍然需要从中获取FILE对象。
所以有:
我猜测有一个标签对象,因为我在表单中有一个标签。我假设FORM对象中包含的数据最多。
使用Firebug和DOM选项卡,文件中包含我想要的属性列表。
所以,我想这是找出对象中属性名称的一种方法。
传递this
代替this.parentNode
并不适用于Google Apps脚本HTML服务。如果我只是用输入对象传递this
,我会得到一个零属性为null的错误,或类似的错误。看起来图像成为FileUpload类的一部分。
我找到了显示文件上传的文档: HTML Service Forms File Upload
答案 0 :(得分:0)
是的,有区别。在浏览器中,this
关键字将创建一个对象,其中包含有关this
参考点中元素的信息。并且对象内部可以有对象。例如,INPUT对象内的FILE对象,位于FORM对象内部。
要从FORM对象中获取INPUT对象,可以使用INPUT标记中的name
属性。
//picOneUpload is the name attribute of the FILE input element
console.log("Input Object: " + frmData.picOneUpload);
然后,要从INPUT对象中获取FILE对象,可以使用files
属性。
var file = frmData.picOneUpload.files[0];
console.log("file: " + file);
浏览器似乎在对象中添加了一个描述性名称,以帮助理解对象的来源以及可能存在的位置。
似乎当另一个对象内部存在对象时,可能根本没有任何键名。因此,尝试枚举键名以尝试查找如何访问该对象中的信息可能对您没有帮助。我碰巧在一些网站上看到一个例子,它使用files
属性名从文件上传选择器中获取FILE对象中的文件blob。所以,我试过了,我发现对象中有数据,否则我可能会有空。
找出对象中可能包含的内容的一种方法是使用类似Firebug的东西检查对象来自的元素,并在DOM中查找属性。例如,有files
,files
下有:大小,类型,名称等。
答案 1 :(得分:0)
我可以从对象中获取所有属性名称。我曾想过,也许Caja正在采取措施防止用户从使用this
创建的对象中获取数据。我只需要用FOR LOOP循环。
for (var theProperties in frmData) {
console.log('theProperties: ' + theProperties);
console.log('loop content: ' + frmData[theProperties]);
};
我应该从一开始就这样做。我只需使用element属性就可以从FORM对象中获取ELEMENT对象。
console.log("elements: " + frmData.elements);