我从工作表数据中获取 JSON 使用已部署的应用程序脚本
浏览器中的 JSON 数据看起来正确
但是当我将 URL 添加到名为 Kumu.io 的应用程序以直观地表示数据时
我收到 CORS 错误消息
Please make sure the url below is valid and CORS is enabled.
如何为此部署的脚本启用 CORS?
谢谢
包含数据和代码的 Google 表格 https://docs.google.com/spreadsheets/d/12ygFGlEbqosGDj_4VSg6pzTjnHn58XuLAtmMpkdoUzM/edit?usp=sharing
应用程序脚本
/**
* Test the original functionality of returning all objects
* in the spreadsheet in JSON.
*/
function test1() {
return runTest_({
parameters : {
id : "12ygFGlEbqosGDj_4VSg6pzTjnHn58XuLAtmMpkdoUzM",
sheet : "Elements",
header : 1,
startRow : 2,
}
});
}
/**
* Basic test logs a request and response. Use View -> Logs to check if it's
* correct.
* (In the future maybe actually check equality to expected output.)
* @param request The HTTP request to test
*/
function runTest_(request) {
console.log(request);
console.log(doGet(request).getContent().toString());
}
/**
* Main method is called when the script receives a GET request.
* Receives the request, generates and returns the output.
*/
function doGet(request) {
// Get request params.
var sheetKey = request.parameters.id;
var sheetName = request.parameters.sheet;
var callback = request.parameters.callback;
var headerRow = request.parameters.header;
var startRow = request.parameters.startRow;
// Parse the spreadsheet.
var spreadsheet = SpreadsheetApp.openById(sheetKey);
var keys = getHeaderRowKeys_(spreadsheet, sheetName, headerRow);
var data = readData_(spreadsheet, sheetName, keys, startRow);
// Filter for matching terms.
data = data.filter(function(entry) {
var matches = true;
for (var k in keys) {
var key = keys[k].replace(/\s+/g, '_');
var searchTerm = request.parameters[key];
// Use the string form of the value since params are strings by default
if (searchTerm != undefined)
matches = matches && ("" + entry[key] == searchTerm);
}
// Matches is true iff all params are undefined or all values for keys match.
return matches;
});
// Write and return the response.
var response = JSON.stringify({ elements: data });
var output = ContentService.createTextOutput();
if (callback == undefined) {
// Serve as JSON
output.setContent(response).setMimeType(ContentService.MimeType.JSON);
} else {
// Serve as JSONP
output.setContent(callback + "(" + response + ")")
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
return output;
}
/**
* Get a row in a spreadsheet as an Object, using the values in the header row as
* keys and the corresponding row values as the values.
*
* @param spreadsheet Spreadsheet object housing the sheet and header
* @param sheetName Name of the specific sheet in the spreadsheet with the data
* @param properties Optional array of keys to use for the row values. Default is the first row.
* @param startRowNum Optional top row number of the rows to parse. The default is
* the second row (i.e., below the header).
*/
function readData_(spreadsheet, sheetName, properties, startRowNum) {
if (typeof properties == "undefined") {
properties = getHeaderRowKeys_(spreadsheet, sheetName);
}
var rows = getDataRows_(spreadsheet, sheetName, startRowNum);
var data = [];
for (var r = 0, l = rows.length-1; r < l; r++) {
var row = rows[r];
var record = {};
for (var p in properties) {
record[properties[p]] = row[p];
}
data.push(record);
}
return data;
}
/**
* Parse spreadsheet data as an array of Javascript Objects.
*
* @param spreadsheet Spreadsheet object with the data to get
* @param sheetName Name of the specific sheet in the spreadsheet with the data
* @param startRowNum Optional top row number of the rows to parse. The default is
* the second row (i.e., below the header).
*/
function getDataRows_(spreadsheet, sheetName, startRowNum) {
if (typeof startRowNum == "undefined") startRowNum = 2;
var sheet = spreadsheet.getSheetByName(sheetName);
return sheet.getRange(startRowNum, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
}
/**
* Return the array of keys used in the header, replacing whitespace with underscores.
*
* @param spreadsheet Spreadsheet object housing the sheet and header
* @param sheetName Name of the specific sheet in the spreadsheet whose header values to get
* @param rowNum Optional exact row number of the header. Default is the first row.
*/
function getHeaderRowKeys_(spreadsheet, sheetName, rowNum) {
if (typeof rowNum == "undefined") rowNum = 1;
return getHeaderRow_(spreadsheet, sheetName, rowNum).map(function(value) {
return value.replace(/\s+/g, '_');
});
}
/**
* Get the values in the header row of the given sheet in a spreadsheet
*
* @param spreadsheet Spreadsheet object housing the sheet and header
* @param sheetName Name of the specific sheet in the spreadsheet whose header values to get
* @param rowNum Exact row number of the header.
*/
function getHeaderRow_(spreadsheet, sheetName, rowNum) {
var sheet = spreadsheet.getSheetByName(sheetName);
return sheet.getRange(rowNum, 1, 1, sheet.getLastColumn()).getValues()[0];
}
这只是我的猜测。从您的以下情况来看,
浏览器中的 JSON 数据看起来正确 但是当我将 URL 添加到名为 Kumu.io 的应用程序以直观地表示数据时 我收到 CORS 错误消息
并且,根据我访问您的 Web 应用程序显示 URL 的结果,
我猜测您当前问题的原因可能是由于您的网络应用程序的设置所致。因此,当我看到您提供的电子表格的 Google Apps 脚本项目时,我注意到您的 Web Apps 的设置如下。
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
在这种情况下,为了访问Web Apps,需要登录Google帐户。虽然我不确定
Kumu.io
或 But when I add the URL to an app called Kumu.io to visually represent the data
,但我猜这可能是您当前问题的原因。
在这种情况下,请通过以下设置更新您的网络应用程序。
Execute as: me
Who has access to the app: Anyone
如果要修改
appsscript.json
,请按如下方式修改。
来自
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
致
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
通过此修改,无需登录 Google 帐户即可访问您的 Web 应用程序。
顺便说一句,当您修改Web Apps的Google Apps脚本时,请将部署修改为新版本。这样,修改后的脚本就会反映在Web Apps中。请注意这一点。
您可以在我的报告“重新部署 Web 应用程序而不更改新 IDE 的 Web 应用程序的 URL(作者:我)”中查看详细信息。