Что такое UrlFetchApp и для чего он нужен?
UrlFetchApp — это сервис в Google Apps Script, который позволяет скриптам отправлять HTTP(S) запросы к другим веб-сервисам. Он выступает в роли клиента, способного взаимодействовать с API, получать данные с веб-сайтов и отправлять информацию на удаленные серверы. Используя UrlFetchApp, можно автоматизировать задачи, связанные с обменом данными между Google таблицами, документами или другими сервисами Google и внешними источниками.
Что такое HTTP-заголовки и их роль в веб-запросах?
HTTP-заголовки – это пары ключ-значение, которые передают дополнительную информацию о запросе или ответе между клиентом (например, браузером или UrlFetchApp) и сервером. Они сообщают о типе контента, используемой кодировке, авторизации, кешировании и других важных деталях. Заголовки играют ключевую роль в установлении соединения и обеспечении правильной обработки данных.
Зачем управлять заголовками в UrlFetchApp?
Управление заголовками необходимо для:
Авторизации: Многие API требуют передачи токенов или ключей API в заголовке Authorization.
Согласования контента: Указание Content-Type в заголовке необходимо для корректной отправки данных в нужном формате (JSON, XML, form data).
Эмуляции браузера: Установка заголовка User-Agent позволяет имитировать запрос от определенного браузера.
Управления кешированием: Заголовки позволяют указывать, как браузеру или другим клиентам кешировать ресурсы.
Решения проблем CORS: Взаимодействие с API, требующими определенных настроек CORS (Cross-Origin Resource Sharing), может потребовать управления заголовками.
Получение заголовков ответа с помощью UrlFetchApp
Отправка простого GET-запроса и получение ответа
Простейший пример отправки GET-запроса:
/**
* Отправляет GET-запрос к указанному URL.
* @param {string} url URL для запроса.
* @return {HTTPResponse} Ответ от сервера.
*/
function fetchUrl(url: string): GoogleAppsScript.URL_Fetch.HTTPResponse {
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url);
return response;
}
const url: string = 'https://www.example.com';
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = fetchUrl(url);
const content: string = response.getContentText();
Logger.log(content);
Метод getAllHeaders(): получение всех заголовков ответа
Метод getAllHeaders() возвращает объект, содержащий все заголовки ответа в виде пар ключ-значение.
/**
* Получает все заголовки ответа.
* @param {string} url URL для запроса.
* @return {object} Объект, содержащий все заголовки.
*/
function getAllResponseHeaders(url: string): object {
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url);
const headers: object = response.getAllHeaders();
return headers;
}
const url: string = 'https://www.example.com';
const allHeaders: object = getAllResponseHeaders(url);
Logger.log(allHeaders);
Метод getHeader(name): получение конкретного заголовка по имени
Метод getHeader(name) позволяет получить значение конкретного заголовка по его имени. Регистр имени заголовка не имеет значения.
/**
* Получает значение конкретного заголовка ответа по имени.
* @param {string} url URL для запроса.
* @param {string} headerName Имя заголовка.
* @return {string | null} Значение заголовка или null, если заголовок не найден.
*/
function getSpecificResponseHeader(url: string, headerName: string): string | null {
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url);
const headerValue: string | null = response.getHeader(headerName);
return headerValue;
}
const url: string = 'https://www.example.com';
const contentType: string | null = getSpecificResponseHeader(url, 'Content-Type');
Logger.log(contentType);
Пример: извлечение Content-Type и Content-Length
/**
* Извлекает Content-Type и Content-Length из заголовков ответа.
* @param {string} url URL для запроса.
*/
function extractContentTypeAndLength(url: string): void {
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url);
const contentType: string | null = response.getHeader('Content-Type');
const contentLength: string | null = response.getHeader('Content-Length');
Logger.log(`Content-Type: ${contentType}`);
Logger.log(`Content-Length: ${contentLength}`);
}
const url: string = 'https://www.example.com';
extractContentTypeAndLength(url);
Установка заголовков запроса с помощью UrlFetchApp
Обзор опций запроса UrlFetchApp
При использовании UrlFetchApp.fetch() можно передать второй аргумент – объект с опциями запроса. Этот объект позволяет настроить различные аспекты запроса, включая метод (GET, POST, PUT, DELETE), полезную нагрузку (payload), заголовки и другие параметры.
Ключ headers: добавление пользовательских заголовков
Для установки заголовков запроса используется ключ headers в объекте опций. Значением ключа headers является объект, где ключи – это имена заголовков, а значения – значения заголовков.
/**
* Отправляет запрос с пользовательскими заголовками.
* @param {string} url URL для запроса.
* @param {object} headers Объект с заголовками запроса.
* @return {HTTPResponse} Ответ от сервера.
*/
function fetchWithCustomHeaders(url: string, headers: object): GoogleAppsScript.URL_Fetch.HTTPResponse {
const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
'method': 'get',
'headers': headers
};
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url, options);
return response;
}
const url: string = 'https://www.example.com';
const customHeaders: object = {
'X-Custom-Header': 'My Custom Value',
'User-Agent': 'MyAppScript/1.0'
};
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = fetchWithCustomHeaders(url, customHeaders);
Logger.log(response.getContentText());
Примеры использования различных заголовков (User-Agent, Authorization, Content-Type)
User-Agent: Имитирует определенный браузер или приложение.
Authorization: Передает учетные данные для доступа к API (например, токен Bearer).
Content-Type: Указывает формат отправляемых данных (например, application/json, application/x-www-form-urlencoded).
// Authorization
const authHeaders: object = {
'Authorization': 'Bearer YOUR_API_TOKEN'
};
// Content-Type
const jsonHeaders: object = {
'Content-Type': 'application/json'
};
Важность правильной установки Content-Type при отправке данных
Правильная установка Content-Type крайне важна, особенно при отправке данных методом POST, PUT или PATCH. Сервер должен знать, в каком формате пришли данные, чтобы корректно их обработать. Если указать неправильный Content-Type, сервер может не понять запрос, что приведет к ошибкам.
Обработка распространенных проблем с заголовками
Ошибки при установке неправильных заголовков
Установка некорректных или неподдерживаемых заголовков может привести к ошибкам со стороны сервера. Внимательно изучите документацию API, чтобы узнать, какие заголовки ожидаются и в каком формате.
Проблемы с CORS и заголовком Access-Control-Allow-Origin
CORS (Cross-Origin Resource Sharing) – механизм безопасности браузера, который ограничивает запросы между разными доменами. Если вы получаете ошибки CORS, это означает, что сервер, к которому вы обращаетесь, не разрешает запросы с вашего домена. Для решения этой проблемы сервер должен отправлять заголовок Access-Control-Allow-Origin с указанием разрешенного домена (или *, что разрешает запросы со всех доменов, но не рекомендуется с точки зрения безопасности).
Ограничения на заголовки, устанавливаемые в Google Apps Script
Google Apps Script накладывает определенные ограничения на заголовки, которые можно устанавливать. Например, нельзя изменять заголовки, связанные с управлением кешированием (Cache-Control, Expires). Эти ограничения связаны с безопасностью и стабильностью платформы.
Практические примеры использования заголовков в UrlFetchApp
Авторизация через API с использованием заголовка Authorization
Многие API требуют авторизацию через заголовок Authorization с использованием токена Bearer.
/**
* Получает данные из API с использованием авторизации Bearer.
* @param {string} url URL API.
* @param {string} apiToken API токен.
* @return {string} JSON ответ от API.
*/
function fetchDataWithAuth(url: string, apiToken: string): string {
const headers: object = {
'Authorization': `Bearer ${apiToken}`
};
const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
'method': 'get',
'headers': headers
};
const response: GoogleAppsScript.URL_Fetch.HTTPResponse = UrlFetchApp.fetch(url, options);
return response.getContentText();
}
// Пример использования
const apiUrl: string = 'https://api.example.com/data';
const apiKey: string = 'YOUR_API_KEY';
const data: string = fetchDataWithAuth(apiUrl, apiKey);
Logger.log(data);
Отправка данных в формате JSON с правильным заголовком Content-Type
При отправке JSON-данных необходимо установить заголовок Content-Type: application/json.
/**
* Отправляет JSON данные на сервер.
* @param {string} url URL для отправки данных.
* @param {object} data Объект с данными для отправки в формате JSON.
*/
function sendJsonData(url: string, data: object): void {
const payload: string = JSON.stringify(data);
const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions = {
'method': 'post',
'contentType': 'application/json',
'payload': payload
};
UrlFetchApp.fetch(url, options);
}
// Пример использования
const postUrl: string = 'https://api.example.com/endpoint';
const jsonData: object = {
'key1': 'value1',
'key2': 'value2'
};
sendJsonData(postUrl, jsonData);
Обработка редиректов и проверка заголовка Location
При редиректе сервер возвращает заголовок Location, указывающий на новый URL. UrlFetchApp по умолчанию следует за редиректами, но можно отключить это поведение и самостоятельно обрабатывать редиректы, анализируя заголовок Location.
Логирование и отладка заголовков запросов и ответов
Для отладки проблем, связанных с заголовками, полезно логировать заголовки запросов и ответов. Это можно сделать, добавив логирование в функции отправки запросов и обработки ответов. Используйте Logger.log() для вывода информации в лог Google Apps Script.