本文详细介绍了在google apps script web应用中,客户端javascript如何与服务器端脚本进行高效且正确的数据交互。重点阐述了`google.script.run`的异步特性及其`withsuccesshandler`回调机制,纠正了常见的同步调用误区,并提供了优化后的客户端代码示例,确保数据能够从服务器端正确传递并被客户端处理。
在Google Apps Script开发的Web应用中,客户端(HTML页面中的JavaScript)与服务器端(.gs文件中的Apps Script代码)之间的通信是一个核心概念。客户端无法直接访问服务器端变量或同步执行服务器端函数并获取返回值,因为这种交互是异步的。
google.script.run是客户端JavaScript调用服务器端Apps Script函数的关键接口。然而,许多开发者初次使用时常会遇到一个误区:试图像调用普通JavaScript函数一样,直接从google.script.run表达式中获取返回值。
核心要点:
在提供的代码示例中,存在两个主要问题导致“getdatafromserver() is not a function”错误或无法正确传递变量:
尝试通过google.script.run调用客户端函数: 原始代码片段:
document.getElementById('btn_btn1').addEventListener('click', async function test(){
await google.script.run.withSuccessHandler(showData).getdatafromserver()
})这里尝试通过google.script.run调用名为getdatafromserver()的函数。然而,getdatafromserver()是一个在Index.html中定义的客户端JavaScript函数,而不是在Code.gs中定义的服务器端函数。google.script.run只能调用服务器端函数,因此会报错。
误解google.script.run的返回值: 原始代码片段:
function getdatafromserver(){
temp = id_input.value
var array1 = google.script.run.withSuccessHandler(data =>{
datatable1 = data
}).get_range_by_id(temp)
return datatable1 // 此时 datatable1 可能尚未被赋值
}在这个客户端函数中,google.script.run.withSuccessHandler(...).get_range_by_id(temp)是一个异步操作。当return datatable1执行时,服务器端函数可能还没有执行完毕,data也还没有传递给withSuccessHandler的回调函数,因此datatable1可能仍是未定义或旧值。google.script.run本身并不返回服务器端函数的结果。
要正确实现从客户端获取用户输入(如ID),发送到服务器端处理,并将处理结果返回客户端显示,应遵循以下模式:
根据上述原则,对Index.html中的JavaScript代码进行如下修改:
修改说明:
服务器端代码(Code.gs)中的函数,如get_range_by_id(id1),其逻辑是正确的,它负责根据传入的ID从Google Sheet中获取相应的数据行并返回。这些函数是google.script.run可以调用的目标。
// ... (之前的 getData, read_id, include 函数) ...
function find_id(id1){
var list_index = []
var id_array = read_id()
for(i = 1; i<= id_array.length;i++){
if(id1 == id_array[i]){
list_index.push(i)
}
}
if(list_index.length > 0){
return list_index.at(-1)
}else{
return "ID isn't existed"
}
}
function get_range_by_id(id1){
var row_num = find_id(id1)
// 确保 row_num 是有效数字,并且 getData() 返回的是一个二维数组
if (typeof row_num === 'number' && row_num >= 0) {
var all_data = getData();
if (all_data && row_num < all_data.length) {
return [all_data[row_num]]; // 返回一个包含目标行的二维数组
}
}
return []; // 如果找不到或发生错误,返回空数组
}注意: 服务器端get_range_by_id函数中,getData()[row_num]可能返回一个单行数组,但DataTable通常期望一个二维数组(行数组的数组)。因此,[getData()[row_num]]的写法是正确的,它将单行数据封装成一个包含一个元素的二维数组。同时,增加了对row_num有效性的检查,以提高健壮性。
当您修改了Google Apps Script项目的代码(无论是.gs文件还是HTML文件),特别是作为Web应用部署时,请务必部署一个新的版本。仅仅保存代码不足以让Web应用反映最新的更改。
部署新版本步骤:
通过部署新版本,确保您的Web应用始终运行最新且正确的代码。
掌握google.script.run的异步特性和withSuccessHandler回调机制是构建健壮Google Apps Script Web应用的关键。通过将客户端操作和服务器端逻辑清晰分离,并利用回调函数处理异步结果,可以有效地实现客户端与服务器端之间的数据交互,提升应用的响应性和用户体验。