master
gman 6 months ago
parent a75989c9ad
commit 35426c8755

@ -10,6 +10,7 @@ export default defineConfig({
starlight({
title: 'Практическое введение в веб-картографию',
description: 'Веб-картография и веб-картографирование: практическое пособие',
favicon: '/icon.png',
head: [
{
tag: 'script',
@ -18,6 +19,14 @@ export default defineConfig({
'data-goatcounter': "https://webcartography.goatcounter.com/count",
async: true
}
},
{
tag: 'link',
attrs: {
rel: 'icon',
href: '/favicon.ico',
sizes: '32x32',
},
}
],
locales: {

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>

Before

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -3,7 +3,6 @@ title: API
---
import { Card, FileTree, LinkCard, TabItem, Tabs } from '@astrojs/starlight/components';
import Question from '../../components/Question.astro';
import MultipleChoice from '../../components/MultipleChoice.astro';
import Option from '../../components/Option.astro';

@ -4,6 +4,8 @@ draft: true
---
import { Card, FileTree, LinkCard, TabItem, Tabs } from '@astrojs/starlight/components';
import MultipleChoice from '../../components/MultipleChoice.astro';
import Option from '../../components/Option.astro';
В этой главе мы рассмотрим
@ -16,13 +18,27 @@ import { Card, FileTree, LinkCard, TabItem, Tabs } from '@astrojs/starlight/comp
## Бэкенд
Мы уже знаем, что веб-приложения можно разделить на клиентскую и серверную части. Разработку клиентской части называют фронтендом. Разработку серверной части называют бэкендом. Фронтенд общается с бэкендом через API. Бэкенд предоставляет метода API, а фронтенд к ним обращается.
Мы уже знаем, что веб-приложения можно разделить на клиентскую и серверную части. Разработку клиентской части называют фронтендом. Разработку серверной части называют бэкендом. Фронтенд общается с бэкендом через API. Бэкенд предоставляет методы API, а фронтенд к ним обращается.
![alt text](../../assets/image-17.png)
Когда происходит вызов метода API -- запрос определённого URL -- выполняется соответствующая серверная функция. Для программирования серверных функций могут использоваться различные языки программирования Python, Go, Rust и даже JavaScript (NodeJS).
В предыдущем занятии мы обращались к бэкенду через API, а в этот раз разработаем бэкенд сами. Наш бэкенд мы разработаем на языке Python с использованием библиотеки Flask.
<Card title='В какой вкладке инструментов разработчика можно увидеть запросы, который выполняет браузер на веб-странице?'>
<MultipleChoice>
<Option>
Элементы (Elements)
</Option>
<Option isCorrect>
Сеть (Network)
</Option>
<Option >
Консоль (Console)
</Option>
</MultipleChoice>
</Card>
В предыдущем упражнении мы обращались к бэкенду через готовый API, а в этот раз разработаем бэкенд сами. Наш бэкенд мы разработаем на языке Python с использованием библиотеки Flask.
## Подготовка
@ -158,7 +174,7 @@ def city_by_id(id):
### Подключение данных и CORS
Наш бэкенд возвращает данные в формате GeoJSON, поэтому мы можем сразу подключить их в нашу карту.
Наш бэкенд возвращает данные в формате GeoJSON, поэтому мы можем сразу подключить их в нашу карту. Однако на карте мы не увидим искомых городов. Чтобы узнать почему, проверим вкладку "Сеть" в инструментах разработчика. У запроса к списку городов мы увидим надпись **Ошибка CORS**.
```js title=main.js
map.on("load", () => {
@ -199,8 +215,6 @@ map.on("load", () => {
})
```
Однако на карте мы не увидим искомых городов. Чтобы узнать почему, проверим вкладку "Сеть" в инструментах разработчика. У запроса к списку городов мы увидим надпись **Ошибка CORS**.
Механизм CORS -- Cross-Origin Resource Sharing -- призван повысить безопасность веб-страницы. Нам, чтобы избежать ошибки CORS, надо указать, что API может отвечать на запросы любых веб-страниц.
> CORS -- это история про *веб-страницы*, поэтому выполняя запросы к API напрямую мы с ней не сталкивались.
@ -230,7 +244,7 @@ def city_by_id(id):
return r
```
После добавления заголовков о том, что API может обслуживать любые веб-страницы, в ответ мы получаем наш список городов в формате GeoJSON.
После добавления заголовков о том, что API готов отдавать данные на любые веб-страницы, в ответ мы получаем наш список городов в формате GeoJSON, который выводится на карту.
### Выбор года
@ -294,7 +308,7 @@ map.on("load", () => {
</body>
```
При клике будем выполнять запрос к методу API, который возвращает подробную информацию о городе. Здесь мы работаем с асинхронностью самостоятельно.
При клике по точке города на карте будем выполнять запрос к методу API, который возвращает подробную информацию о городе. Здесь мы работаем с асинхронностью самостоятельно.
```js title=main.js
map.on("load", () => {
@ -339,8 +353,6 @@ map.on("load", () => {
При желании посмотрите [полный код](https://github.com/gtitov/flask-maplibre-map) и [возможный результат](https://gtitov.github.io/flask-maplibre-map/).
## Упражнения
1. Создайте метод, который вернёт список доступных годов
@ -351,6 +363,13 @@ map.on("load", () => {
Бэкендер: можно убрать из метода для списка городов лишние атрибуты<br/>Фронтендер: на клик по объекту можно не обращаться к серверу, а использовать данные из атрибутов объекта
</details>
## Контрольные вопросы
1. Сформулируйте запрос для получения всех данных из таблицы `cities` базы данных `cities.sqlite`
1. На каком языке программирования сформулирован этот запрос?
1. В каком формате бэкенд возращает подробные данные о городе по идентификатору?
1. Для чего к ответу добавляется заголовок `"Access-Control-Allow-Origin": "*"`?
## Чтение
1. Что такое CORS / Дока [[↗]](https://doka.guide/tools/cors/)

Loading…
Cancel
Save