21 октября 2011, 07:29 (4783 дня назад, №8816)Google Spreadsheets - серверная часть для Javascript клиента
Бывает так, что для web проекта на JS/HTML необходима простая база данных с интерфейсом, который позволял бы обычному пользователю добавлять и редактировать записи. В ряде случаев можно обойтись без создания серверной части и всяких форм ввода, воспользовавшись Google Spreadsheets API .
Создаём таблицу. Делаем Share / Anyone with link , затем File / Publish to the Web.
Выбираем лист (обычно Sheet1). В разделе Get a link to the published data выбираем ATOM (этот пункт есть только для обычных гуглоаккаунтов. Для Google Apps аккаунтов его почему-то пока нет).
Внизу появляется ссылка на Atom feed для данной таблицы, выглядит примерно так:
https://spreadsheets.google.com/feeds/list/1As7ltzfMZnqJdEVoaEFCVXlHaGlWVnR0YUxjNWhEN3c/od6/public/basic?hl=en_US
Нас интересуют здесь два параметра:
key = 1As7ltzfMZnqJdEVoaEFCVXlHaGlWVnR0YUxjNWhEN3c
workSheetId = od6
Нам нужен не xml, а json (причём, кроссдоменный).
Допустим, мы хотим получать данные с разбивкой по ячейкам. Строка запроса будет выглядеть следующим образом:
http://spreadsheets.google.com/feeds/cells/1As7ltzfMZnqJdEVoaEFCVXlHaGlWVnR0YUxjNWhEN3c/od6/public/values?alt=json-in-script&callback=myFunc
Код:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Reading google spreadsheet data via API</title>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/io/script.js"></script>
<script>
dojo.ready(function()
{
// Fetching data from Google Spreadsheet (code by Frog)
function fetchData()
{
var jsonpArgs =
{
url: 'http://spreadsheets.google.com/feeds/cells/1As7ltzfMZnqJdEVoaEFCVXlHaGlWVnR0YUxjNWhEN3c/od6/public/values?alt=json-in-script',
callbackParamName: "callback",
timeout: 5000,
handleAs: 'json',
load: function(response)
{
var html = '';
console.log('fetchData response:', response);
html += 'Получено данных в ячейках: ' + response.feed.openSearch$totalResults.$t + '<p>';
html += 'Последнее обновление таблицы: ' + response.feed.updated.$t + '<p>';
dojo.forEach(response.feed.entry, function(cell)
{
html += 'Строка:' + cell.gs$cell.row + ' Столбец:' + cell.gs$cell.col + ' Содержимое: ' + cell.gs$cell.$t + '<br>';
});//forEach
dojo.byId('content').innerHTML = html;
},//load
error: function(error)
{
console.log('fetchData: An unexpected error occurred: ' + error);
}//error
};//jsonpArgs
dojo.io.script.get(jsonpArgs);
}//fetchData()
fetchData();
});
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
Результат:
----------
Получено данных в ячейках: 8
Последнее обновление таблицы: 2011-10-21T02:59:35.293Z
Строка:1 Столбец:1 Содержимое: ячейка A1
Строка:1 Столбец:2 Содержимое: ячейка B1
Строка:2 Столбец:1 Содержимое: ячейка A2
Строка:2 Столбец:2 Содержимое: ячейка B2
Строка:3 Столбец:1 Содержимое: ячейка A3
Строка:3 Столбец:2 Содержимое: ячейка B3
Строка:4 Столбец:1 Содержимое: ячейка A4
Строка:4 Столбец:2 Содержимое: ячейка B4
------
Примечания:
1.Действия по изменению таблицы (insert/update/delete) в отличие от чтения требуют авторизацию и одним GET там не обойдешься.
2.Есть также ряд полезных параметров (сортировка, условия и пр.).
В принципе, подход можно развить довольно далеко. К примеру, Google Apps Scripts позволяет написать скрипты срабатывающие по определённым событиям, в том числе и по времени. Так что серверная часть может получится полезная, если не нужно менять данные с клиента.
Файлы непосредственно в таблицу поместить будет конечно проблематично, но ничто не мешает закачать их в Google Docs или Picasa/Youtube (взависимости от назначения), а в ячейки таблицы вставлять URL. Этот процесс, кстати, тоже можно автоматизировать, но для этого уже придётся попотеть.
Несколько туманен вопрос с количеством запросов в единицу времени, которое Google позволит делать по URL feed'a. В документации по этому поводу ничего не сказано, а в группе вопросы людей остаются без ответа. Вероятно это потому, что Google не хочет предоставлять какие-то гарантированные минимумы. Мораль простая - не стоит использовать это решение на проектах с большим числом запросов в секунду. Впрочем, жалобы на отказы по причине нагрузки редки, как я заметил.
В качестве меры предосторожности можно проверять, был ли изменён лист таблицы без получения данных таблицы (см. про If-None-Match header).
UPDATE: Обнаружил статью - человек делал тоже самое, только через Google Fusion Tables :)