使用 htmlService 和应用程序脚本上传表单和文件不起作用 [英] Form and file upload with htmlService and app script not working

查看:21
本文介绍了使用 htmlService 和应用程序脚本上传表单和文件不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将文件与表单数据一起上传到特定的 google 驱动器文件夹到电子表格中.此代码的电子表格部分有效,但文件上传功能无效.任何解决此问题的帮助将不胜感激.

Code.gs

var submitSSKey = 'SS ID';函数 doGet(e) {var template = HtmlService.createTemplateFromFile('Form.html');template.action = ScriptApp.getService().getUrl();返回模板.评估();}函数 doPost(e) {var template = HtmlService.createTemplateFromFile('Thanks.html');var LoanType = template.name = e.parameter.name;var借用者 = template.department = e.parameter.department;var 数量 = template.message = e.parameter.message;var emailed = template.email = e.parameter.email;var comp = '不适用'var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];var lastRow = sheet.getLastRow();var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[comp,LoanType,borrower,amount,emailed]]);var fileBlob = e.paramater.thefilevar doc = DriveApp.getFolderById('文件夹 ID');doc.createFile(fileBlob)//.rename('新名称');返回模板.评估();}

Form.html

<头><title></title><身体><form action="<?= action ?>"enctype="multipart/form-data" method="post"><table border="0" cellpadding="1" cellspacing="0" style="width: 500px;"><tr><td>名称:</td><td><input name="name" type="text"/></td></tr><tr><td>部门:</td><td><选择名称=部门"><option>选择选项</option><option>收银员</option><option>迎宾</option><option>Runner</option><option>线路控制</option><option>IDB</option><option>未知</option></选择></td></tr><tr><td>电子邮件:</td><td><input name="email" type="text"/></td></tr><tr><td>消息:</td><td><textarea name="message" style="margin: 2px; height: 148px; width: 354px;"></textarea></td></tr><tr><td><p>学校时间表(仅限图像文件):</p></td><td><p><input type="file" id="thefile" name="thefile"></p></td></tr><tr><td><input type="submit" value="Submit"/></td><td>提交后,您将收到一封确认电子邮件;</tr></tbody></form></body>

Thanks.html

<身体><h1>谢谢</h1><p>感谢您的提交.</p>姓名:<?= 姓名 ?><br/>部门:<?= 部门 ?><br/>消息:<?= 消息 ?><br/>电子邮件:<?= 电子邮件 ?><br/>

解决方案

工作示例

HtmlService 不支持 HTML 表单的 post 方法.表单收集的输入元素可以改为使用处理程序函数传递给服务器端函数.有关更多详细信息,请参阅HTML 服务:与服务器功能通信.

这是一个基于您在问题中发布的代码的示例.

Form.html

<div id="formDiv"><!-- 表单提交后表单div将隐藏--><form id="myForm">名称:<输入名称=名称"类型=文本"/><br/>部门:<选择名称=部门"><option>选择选项</option><option>收银员</option><option>迎宾</option><option>Runner</option><option>线路控制</option><option>IDB</option><option>未知</option></选择><br/>电子邮件:<输入名称=电子邮件"类型=文本"/><br/>消息:<textarea name="message";样式=边距:2px;高度:148px;宽度:354px;"></textarea><br/>学校时间表(仅限图像文件):

<div id="inProgress";样式=显示:无;"><!-- 进度开始隐藏,但会在表单提交后显示.-->正在上传.请稍等...

<div id="输出"><!-- 空白 div 将填充Thanks.html";表单提交后.-->

谢谢.html

<h1>谢谢</h1><p>感谢您的提交.</p>姓名:<?= 姓名 ?><br/>部门:<?= 部门 ?><br/>消息:<?= 消息 ?><br/>电子邮件:<?= 电子邮件 ?><br/>文件 URL:<?= fileUrl ?><br/>

代码.gs

var submitSSKey = '--Spreadsheet-key--';var folderId = "--Folder-Id--";函数 doGet(e) {var template = HtmlService.createTemplateFromFile('Form.html');template.action = ScriptApp.getService().getUrl();返回模板.评估();}函数 processForm(theForm) {var fileBlob = theForm.myFile;var folder = DriveApp.getFolderById(folderId);var doc = folder.createFile(fileBlob);//填写响应模板var template = HtmlService.createTemplateFromFile('Thanks.html');var name = template.name = theForm.name;var 部门 = template.department = theForm.department;var message = template.message = theForm.message;var email = template.email = theForm.email;var fileUrl = template.fileUrl = doc.getUrl();//在电子表格中记录提交var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];var lastRow = sheet.getLastRow();var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[name,department,message,email,fileUrl]]);//返回 HTML 文本以显示在页面中.返回 template.evaluate().getContent();}


最初的答案,专注于基本调试:

这段代码最初来自哪里?已经有关于它的多个问题,它可能有助于查看原始教程或示例.

当您将此代码作为已发布的 Web 应用程序运行并提交文件时,您收到的错误是 TypeError: Cannot read property "thefile";来自 undefined. 无需进一步挖掘,这会告诉您在您的代码中使用了一个 undefined 对象.那是什么物体?还不知道,但一个线索是代码正在寻找一个名为 thefile" 的属性.

如果您在编辑器中打开了脚本,并从那里启动了网络应用程序(通过在发布/部署为网络应用程序对话框中单击<代码>测试网络应用程序以获取最新代码),那么您还可以查看执行记录以了解更多详细信息.(在查看"菜单下)您会发现它包含如下内容:

[13-12-25 07:49:12:447 EST] 开始执行[13-12-25 07:49:12:467 EST] HtmlService.createTemplateFromFile([Thanks.html]) [0 秒][13-12-25 07:49:12:556 EST] SpreadsheetApp.openById([--SSID--]) [0.089 秒][13-12-25 07:49:12:557 EST] Spreadsheet.getSheets() [0 秒][13-12-25 07:49:12:626 EST] Sheet.getLastRow() [0.067 秒][13-12-25 07:49:12:627 EST] Sheet.getRange([1, 1, 1, 5]) [0 秒][13-12-25 07:49:12:629 EST] Range.setValues([[[N/A, , Select Option, , ]]]) [0.001 秒][13-12-25 07:49:12:983 EST] 执行失败:TypeError:无法读取属性thefile"从未定义.(第 20 行,文件代码")[总运行时间为 0.17 秒]

我们看到了同样的错误,但现在我们知道了行号.该行包含一个拼写错误:

var fileBlob = e.paramater.thefile^^^^^^^^^^

I'm trying to upload a file to a specific google drive folder along with form data into a spreadsheet. The spreadsheet portion of this code works, but the file upload function does not. Any help on fixing this would be appreciated.

Code.gs

var submissionSSKey = 'SS ID';
function doGet(e) {
      var template = HtmlService.createTemplateFromFile('Form.html');
  template.action = ScriptApp.getService().getUrl();
  return template.evaluate();
}

function doPost(e) {
  var template = HtmlService.createTemplateFromFile('Thanks.html');
  var LoanType = template.name = e.parameter.name;
  var borrower = template.department = e.parameter.department;
  var amount = template.message = e.parameter.message;
  var emailed = template.email = e.parameter.email;
  var comp = 'N/A'

  var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[comp,LoanType,borrower,amount,emailed]]);

  var fileBlob = e.paramater.thefile
  var doc = DriveApp.getFolderById('folder ID');
            doc.createFile(fileBlob)//.rename('New Name');


  return template.evaluate();


}

Form.html

<html>
    <head>
        <title></title>
    </head>
    <body>
    <form action="<?= action ?>" enctype="multipart/form-data" method="post">
    <table border="0" cellpadding="1" cellspacing="0" style="width: 500px;">
    <tbody>
    <tr>
    <td>
    Name:</td>
    <td>
    <input name="name" type="text" /></td>
    </tr>
    <tr>
    <td>
    Department:</td>
    <td>
    <select name="department">
    <option>Select Option</option>
    <option>Cashier</option>
    <option>Greeter</option>
    <option>Runner</option>
    <option>Line Control</option>
    <option>IDB</option>
    <option>Unknown</option>
    </select></td>
    </tr>
    <tr>
    <td>
    Email:</td>
    <td>
    <input name="email" type="text" /></td>
    </tr>
    <tr>
    <td>
    Message:</td>
    <td>
    <textarea name="message" style="margin: 2px; height: 148px; width: 354px;"></textarea></td>
    </tr>
    <tr>
    <td>
    <p>
    School Schedule (Image Files Only):</p>
    </td>
    <td>
    <p>
    <input type="file" id="thefile" name="thefile">
    </p></td>
    </tr>
    <tr>
    <td>
    <input type="submit" value="Submit" /></td>
    <td>
    You will receive an email confirmation upon submission</td>
    </tr>
    </tbody>
    </table>
  </form></body>
</html>

Thanks.html

<html>
  <body>
    <h1>Thanks</h1>
    <p>Thank you for your submission.</p>
    Name: <?= name ?><br/>
    Department: <?= department ?><br/>
    Message: <?= message ?><br/>
    Email: <?= email ?><br/>
  </body>
</html>

解决方案

Edit: Working example

The HtmlService does not support the post method for HTML forms. The input elements collected by a form can be communicated to a server-side function using a handler function instead. For more details, see HTML Service: Communicate with Server Functions.

Here's an example based on the code you've posted in your question.

Form.html

<script>
  // Javascript function called by "submit" button handler,
  // to show results.
  function updateOutput(resultHtml) {
    toggle_visibility('inProgress');
    var outputDiv = document.getElementById('output');
    outputDiv.innerHTML = resultHtml;
  }
  
  // From blog.movalog.com/a/javascript-toggle-visibility/
  function toggle_visibility(id) {
    var e = document.getElementById(id);
    if(e.style.display == 'block')
      e.style.display = 'none';
    else
      e.style.display = 'block';
  }
</script>

<div id="formDiv">
<!-- Form div will be hidden after form submission -->
<form id="myForm">

    Name: <input name="name" type="text" /><br/>
    Department:  <select name="department">
    <option>Select Option</option>
    <option>Cashier</option>
    <option>Greeter</option>
    <option>Runner</option>
    <option>Line Control</option>
    <option>IDB</option>
    <option>Unknown</option>
    </select><br/>
    Email: <input name="email" type="text" /><br/>
    Message: <textarea name="message" style="margin: 2px; height: 148px; width: 354px;"></textarea><br/>
    School Schedule (Image Files Only): <input name="myFile" type="file" /><br/>
  <input type="button" value="Submit"
      onclick="toggle_visibility('formDiv'); toggle_visibility('inProgress');
        google.script.run
          .withSuccessHandler(updateOutput)
          .processForm(this.parentNode)" />
</form>
</div>

<div id="inProgress" style="display: none;">
<!-- Progress starts hidden, but will be shown after form submission. -->
Uploading. Please wait...
</div>

<div id="output">
  <!-- Blank div will be filled with "Thanks.html" after form submission. -->
</div>

Thanks.html

<div>
    <h1>Thanks</h1>
    <p>Thank you for your submission.</p>
    Name: <?= name ?><br/>
    Department: <?= department ?><br/>
    Message: <?= message ?><br/>
    Email: <?= email ?><br/>
    File URL: <?= fileUrl ?><br/>
</div>

Code.gs

var submissionSSKey = '--Spreadsheet-key--';
var folderId = "--Folder-Id--";

function doGet(e) {
  var template = HtmlService.createTemplateFromFile('Form.html');
  template.action = ScriptApp.getService().getUrl();
  return template.evaluate();
}


function processForm(theForm) {
  var fileBlob = theForm.myFile;
  var folder = DriveApp.getFolderById(folderId);
  var doc = folder.createFile(fileBlob);
  
  // Fill in response template
  var template = HtmlService.createTemplateFromFile('Thanks.html');
  var name = template.name = theForm.name;
  var department = template.department = theForm.department;
  var message = template.message = theForm.message;
  var email = template.email = theForm.email;     
  var fileUrl = template.fileUrl = doc.getUrl();
  
  // Record submission in spreadsheet
  var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[name,department,message,email,fileUrl]]);
  
  // Return HTML text for display in page.
  return template.evaluate().getContent();
}


Original answer, which was focused on basic debugging:

Where does this code come from originally? There have been multiple questions about it, and it might be helpful to see the original tutorial or example it was taken from.

When you run this code as a published web app, and submit a file, the error you receive is TypeError: Cannot read property "thefile" from undefined. Without any more digging, this tells you that there's an undefined object being used in your code. What object is that? Don't know yet, but a clue is that the code is looking for a property named "thefile".

If you have the script open in the editor, and launched the webapp from there (by clicking on Test web app for your latest code in the Publish / Deploy as Web App dialog), then you can also check the Execution Transcript for more details. (under View menu) You'll find it contains something like this:

[13-12-25 07:49:12:447 EST] Starting execution
[13-12-25 07:49:12:467 EST] HtmlService.createTemplateFromFile([Thanks.html]) [0 seconds]
[13-12-25 07:49:12:556 EST] SpreadsheetApp.openById([--SSID--]) [0.089 seconds]
[13-12-25 07:49:12:557 EST] Spreadsheet.getSheets() [0 seconds]
[13-12-25 07:49:12:626 EST] Sheet.getLastRow() [0.067 seconds]
[13-12-25 07:49:12:627 EST] Sheet.getRange([1, 1, 1, 5]) [0 seconds]
[13-12-25 07:49:12:629 EST] Range.setValues([[[N/A, , Select Option, , ]]]) [0.001 seconds]
[13-12-25 07:49:12:983 EST] Execution failed: TypeError: Cannot read property "thefile" from undefined. (line 20, file "Code") [0.17 seconds total runtime]

We see that same error, but now we know the line number. That line contains a spelling mistake:

var fileBlob = e.paramater.thefile
                 ^^^^^^^^^

这篇关于使用 htmlService 和应用程序脚本上传表单和文件不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆