使用 AJAX 将 google 脚本中的 object 分配给局部变量
Assign object from google scripts to local variable using AJAX
我写了一个自定义 Google 脚本,它为我输出一个 object,我希望能够调用它并将它分配给一个变量,该变量然后用于在网站。
HTML Header:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>JQVMap - World Map</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<link href="../dist/jqvmap.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="../dist/jquery.vmap.js"></script>
<script type="text/javascript" src="../dist/maps/jquery.vmap.world.js" charset="utf-8"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.deaths.js"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.infected.js"></script>
<script>
jQuery(document).ready(function () {
jQuery('#vmap').vectorMap({
map: 'world_en',
backgroundColor: '#333333',
color: '#ffffff',
hoverOpacity: 0.8,
selectedColor: '#3498DB',
enableZoom: true,
showTooltip: true,
scaleColors: ['#F3A291', '#FF4F3B'],
values: infected_data,
normalizeFunction: 'polynomial',
onLabelShow: function (event, label, code) {
label.html('<div class="map-tooltip"><h1 class="header"> ' + label.html() + '</h1><p class="description">Infected: ' + infected_data[code] + '</p><p class="description">Deaths: ' + death_data[code] + '</p></div>');
}
});
});
</script>
</head>
Google 脚本文件:
function doGet() {
var result = {};
var infected = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
var death = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
result = makeObject(infected);
return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}
function makeObject(multiArr) {
var obj = {};
var countrystats = {};
var headers = multiArr.shift();
for (var i = 0; i < headers.length; i++) {
countrystats[i] = multiArr.map(function (app) {
return app[i];
})
}
for (var m = 0; m < countrystats[1].length; m++) {
obj[countrystats[1][m]] = 0;
}
for (var j = 0; j < countrystats[1].length; j++) {
var TempVar;
TempVar = obj[countrystats[1][j]];
obj[countrystats[1][j]] = TempVar + countrystats[3][j];
}
return obj;
}
Google 脚本输出(使用 JSON 查看 chrome 扩展):
{
cn: 8134,
th: 23,
mo: 7,
us: 5,
jp: 11,
kr: 4,
sg: 10,
vn: 2,
fr: 5,
np: 1,
my: 8,
ca: 3,
ci: 1,
lk: 1,
au: 9,
de: 4,
fn: 1
}
这是一个 public link,上面有我想要的 object/data(与上面显示的 object 相同):网络应用程序:https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec
所以基本上任何使用它的人都应该能够访问它。我只需要一种将该数据分配给本地 JS 变量的方法。 google 表格脚本作为网络应用程序发布。如果我没记错的话,有一个设置允许任何人访问它,甚至是匿名的。
这是我对 AJAX 请求的尝试:
var url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
var infected_data = jQuery.ajax({
crossDomain: true,
url: url,
method: "GET",
//dataType: "jsonp"
});
如果我取消注释 jsonp,我会得到一个错误:
jquery-1.11.3.min.js:5 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://script.googleusercontent.com/macros/echo?user_content_key=JXkCjiJjhcjndRREjoGyVNkZNkD-HvKpEPkpicQBm9nR9OkxjGXdYuOPsLxbJf-B9Rgifl5NWMtzgjfVGuMdGxTJrjKnRpdcOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHazTNYZyoqG0ZuVXpWSNdoeLErB4AfUCNPKJHgELe5WaAmN5SlwIhonlWkkbFzR8kUwjKrMtdq9u-YqreD7W_KJ_aVqKVBTehAuogPCoZCfVc4yJf5ieDCdMDbXQ8FZZq8iSedsk1Px1LnPBLM8W-ZRcknnbJNT8dS525XG1pNEBR&lib=Mw_Scq3iKhByBS86NJpd_CngcdEShCw7K with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
如果删除它,我不会收到任何错误。但是,我仍然无法在我的交互式地图(我的应用程序)上看到数据。
使用获取:
const url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
// Declare an async function
const getData = async () => {
// Use the await keyword to let JS know this variable has some latency so it should wait for it to be filled
// When the variable is fetched, use the .then() callback to carry on
const DataJSON = await fetch(url).then(response =>
response.json()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(getData());
var infected_data = getData();
将 object 中的整数转换为字符串
object 需要采用如下格式:
var infected_data = {
cn: "83",
th: "0",
mo: "0",
au: "0",
sg: "0",
tw: "0",
us: "0",
jp: "0",
my: "0",
kr: "0",
fx: "0",
vn: "0",
kh: "0",
ca: "0",
ci: "0",
np: "0",
lk: "0",
};
您可能遇到异步调用的问题,这意味着您在数据实际从 Google 的服务器返回之前读取数据。尝试使用 promises
和 fetch
API
const url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
// Declare an async function
const getData = async () => {
// Use the await keyword to let JS know this variable has some latency so it should wait for it to be filled
// When the variable is fetched, use the .then() callback to carry on
const DataJSON = await fetch(url).then(response =>
response.json()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(await getData())
假设数据不敏感,你可以使用 jsonp 绕过 cors:
服务器端:
return ContentService.createTextOutput("infect(" +JSON.stringify(result)+ ")").setMimeType(ContentService.MimeType.JAVASCRIPT);
客户端:
<script>function infect(data){ infectedData = data }</script>
<script src="URL_OF_YOUR_SCRIPT"></script>
参考文献:
回答将整数转换为字符串的问题:
尝试这样的事情:
function toString(o) {
Object.keys(o).forEach(k => {
if (typeof o[k] === 'object') {
return toString(o[k]);
}
o[k] = '' + o[k];
});
return o;
}
我写了一个自定义 Google 脚本,它为我输出一个 object,我希望能够调用它并将它分配给一个变量,该变量然后用于在网站。
HTML Header:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>JQVMap - World Map</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<link href="../dist/jqvmap.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="../dist/jquery.vmap.js"></script>
<script type="text/javascript" src="../dist/maps/jquery.vmap.world.js" charset="utf-8"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.deaths.js"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.infected.js"></script>
<script>
jQuery(document).ready(function () {
jQuery('#vmap').vectorMap({
map: 'world_en',
backgroundColor: '#333333',
color: '#ffffff',
hoverOpacity: 0.8,
selectedColor: '#3498DB',
enableZoom: true,
showTooltip: true,
scaleColors: ['#F3A291', '#FF4F3B'],
values: infected_data,
normalizeFunction: 'polynomial',
onLabelShow: function (event, label, code) {
label.html('<div class="map-tooltip"><h1 class="header"> ' + label.html() + '</h1><p class="description">Infected: ' + infected_data[code] + '</p><p class="description">Deaths: ' + death_data[code] + '</p></div>');
}
});
});
</script>
</head>
Google 脚本文件:
function doGet() {
var result = {};
var infected = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
var death = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
result = makeObject(infected);
return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}
function makeObject(multiArr) {
var obj = {};
var countrystats = {};
var headers = multiArr.shift();
for (var i = 0; i < headers.length; i++) {
countrystats[i] = multiArr.map(function (app) {
return app[i];
})
}
for (var m = 0; m < countrystats[1].length; m++) {
obj[countrystats[1][m]] = 0;
}
for (var j = 0; j < countrystats[1].length; j++) {
var TempVar;
TempVar = obj[countrystats[1][j]];
obj[countrystats[1][j]] = TempVar + countrystats[3][j];
}
return obj;
}
Google 脚本输出(使用 JSON 查看 chrome 扩展):
{
cn: 8134,
th: 23,
mo: 7,
us: 5,
jp: 11,
kr: 4,
sg: 10,
vn: 2,
fr: 5,
np: 1,
my: 8,
ca: 3,
ci: 1,
lk: 1,
au: 9,
de: 4,
fn: 1
}
这是一个 public link,上面有我想要的 object/data(与上面显示的 object 相同):网络应用程序:https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec
所以基本上任何使用它的人都应该能够访问它。我只需要一种将该数据分配给本地 JS 变量的方法。 google 表格脚本作为网络应用程序发布。如果我没记错的话,有一个设置允许任何人访问它,甚至是匿名的。
这是我对 AJAX 请求的尝试:
var url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
var infected_data = jQuery.ajax({
crossDomain: true,
url: url,
method: "GET",
//dataType: "jsonp"
});
如果我取消注释 jsonp,我会得到一个错误:
jquery-1.11.3.min.js:5 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://script.googleusercontent.com/macros/echo?user_content_key=JXkCjiJjhcjndRREjoGyVNkZNkD-HvKpEPkpicQBm9nR9OkxjGXdYuOPsLxbJf-B9Rgifl5NWMtzgjfVGuMdGxTJrjKnRpdcOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHazTNYZyoqG0ZuVXpWSNdoeLErB4AfUCNPKJHgELe5WaAmN5SlwIhonlWkkbFzR8kUwjKrMtdq9u-YqreD7W_KJ_aVqKVBTehAuogPCoZCfVc4yJf5ieDCdMDbXQ8FZZq8iSedsk1Px1LnPBLM8W-ZRcknnbJNT8dS525XG1pNEBR&lib=Mw_Scq3iKhByBS86NJpd_CngcdEShCw7K with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
如果删除它,我不会收到任何错误。但是,我仍然无法在我的交互式地图(我的应用程序)上看到数据。
使用获取:
// Declare an async function
const getData = async () => {
// Use the await keyword to let JS know this variable has some latency so it should wait for it to be filled
// When the variable is fetched, use the .then() callback to carry on
const DataJSON = await fetch(url).then(response =>
response.json()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(getData());
var infected_data = getData();
将 object 中的整数转换为字符串 object 需要采用如下格式:
var infected_data = {
cn: "83",
th: "0",
mo: "0",
au: "0",
sg: "0",
tw: "0",
us: "0",
jp: "0",
my: "0",
kr: "0",
fx: "0",
vn: "0",
kh: "0",
ca: "0",
ci: "0",
np: "0",
lk: "0",
};
您可能遇到异步调用的问题,这意味着您在数据实际从 Google 的服务器返回之前读取数据。尝试使用 promises
和 fetch
API
const url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
// Declare an async function
const getData = async () => {
// Use the await keyword to let JS know this variable has some latency so it should wait for it to be filled
// When the variable is fetched, use the .then() callback to carry on
const DataJSON = await fetch(url).then(response =>
response.json()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(await getData())
假设数据不敏感,你可以使用 jsonp 绕过 cors:
服务器端:
return ContentService.createTextOutput("infect(" +JSON.stringify(result)+ ")").setMimeType(ContentService.MimeType.JAVASCRIPT);
客户端:
<script>function infect(data){ infectedData = data }</script>
<script src="URL_OF_YOUR_SCRIPT"></script>
参考文献:
回答将整数转换为字符串的问题: 尝试这样的事情:
function toString(o) {
Object.keys(o).forEach(k => {
if (typeof o[k] === 'object') {
return toString(o[k]);
}
o[k] = '' + o[k];
});
return o;
}