Sign in Join
Wiki copytemporary

fcl-web/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: fcl-web/ru

OldNewLine
1+## Что такое fpWeb
2+
3+fpWeb можно использовать для создания приложений веб-сервера. Приложение веб-сервера может быть одним из следующих
4+
5+- Приложение CGI
6+- Приложение FastCGI
7+- Модуль Apache
8+- Автономный HTTP-сервер, использующий компоненты HTTP-сервера Free Pascal.
9+- Автономный сервер HTTP с использованием GNU libmicrohttp
10+- Приложение Windows SysHTTP.
11+
12+Во всех случаях модель разработки одинакова: вы регистрируете обработчики для набора URL-адресов (называемых маршрутами), которые будет поддерживать ваше приложение.
13+
14+Затем вы встраиваете эти маршруты в одну из указанных выше сред: Это означает, что вы выбираете объект приложения, который будете использовать.
15+
16+В lazarus IDE у вас есть выбор приложений, когда вы запускаете новый проект. После запуска приложения можно изменить тип приложения, обычно это означает просто изменение имени модуля в разделе uses проекта.
17+
18+В одном двоичном файле можно поддерживать несколько сред, хотя это требует дополнительной работы.
19+
20+fpWeb также предлагает некоторую готовую поддержку для REST-сервера базы данных или для механизмов JSON RPC 2.0. Они построены поверх вышеупомянутой конструкции. Платформа Brook также построена на основе базовой архитектуры, описанной выше.
21+
22+Подробнее об этом можно прочитать в [[fpWeb Tutorial]]
23+
24+## Использование fpWeb вместе с Lazarus
25+
26+### Установка пакета weblaz fpWeb Lazarus
27+
28+Первым делом необходимо установить пакет, который находится по пути lazarus/components/fpweb/weblaz.lpk. Как обычно с пакетами времени разработки, вам придется пересобрать Lazarus.
29+
30+### Создание CGI-приложения
31+
32+После установки пакета weblaz можно создать очень простое веб-приложение CGI, отображающее HTML-страницу, перейдя в меню Lazarus «Файл - Новый ...». Из списка возможных приложений выберите «Приложение CGI», как показано на изображении ниже, которое создаст основной файл проекта CGI и веб-модуль fpweb.
33+
34+![](/wiki-images/e/ec/New_cgi.PNG)
35+
36+TFPWebModule позволяет вам управлять свойствами и событиями с помощью инспектора объектов.
37+
38+Чтобы добавить код для отображения страницы, необходимо добавить обработчик запроса. Для этого дважды щелкните свойство OnRequest в инспекторе объектов, как показано на изображении ниже:
39+
40+![](/wiki-images/3/3d/Webmodule.PNG)
41+
42+В обработчике событий нужно написать HTML-код, который будет отображаться браузером. Чтобы избежать смешивания Pascal и HTML, эту страницу можно загружать из каталога, в котором находится исполняемый файл CGI, с помощью `AResponse.Contents.LoadFromFile()`.
43+
44+Тип ответа должен быть установлен в `AResponse.ContentType`. Для HTML-страниц это должно иметь значение 'text/html;charset=utf-8'.
45+
46+Наконец, для параметра Handled должно быть установлено значение True, чтобы указать, что запрос был успешно обработан (и вернуть в браузер код состояния 200 OK). После добавления этого кода веб-модуль должен выглядеть так:
47+
48+``` pascal
49+unit mainpage;
50+
51+{$mode objfpc}{$H+}
52+
53+interface
54+
55+uses
56+ Classes, SysUtils, FileUtil, HTTPDefs, websession, fpHTTP, fpWeb;
57+
58+type
59+
60+ { TFPWebModule1 }
61+
62+ TFPWebModule1 = class(TFPWebModule)
63+ procedure DataModuleRequest(Sender: TObject; ARequest: TRequest;
64+ AResponse: TResponse; var Handled: Boolean);
65+ private
66+ { private declarations }
67+ public
68+ { public declarations }
69+ end;
70+
71+var
72+ FPWebModule1: TFPWebModule1;
73+
74+implementation
75+
76+{$R *.lfm}
77+
78+{ TFPWebModule1 }
79+
80+procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;
81+ AResponse: TResponse; var Handled: Boolean);
82+begin
83+ AResponse.ContentType := 'text/html;charset=utf-8';
84+ AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');
85+ Handled := True;
86+end;
87+
88+begin
89+ RegisterHTTPModule('TFPWebModule1', TFPWebModule1);
90+end.
91+```
92+
93+### Развертывание приложения CGI
94+
95+В этом разделе предполагается, что используется веб-сервер Apache. Конечно, можно использовать и другие веб-серверы, поддерживающие CGI (nginx, cherokee).
96+
97+Apache можно загрузить здесь: <http://httpd.apache.org/download.cgi> или установить с помощью диспетчера пакетов вашего дистрибутива.
98+
99+При установке Apache по умолчанию все файлы, расположенные в его каталоге cgi-bin, будут обрабатываться как программы CGI, поэтому пользователь не сможет получить доступ к размещенным там простым файлам HTML. Этот каталог можно задать в файле httpd.conf в следующем разделе:
100+
101+ #
102+ # ScriptAlias: определяет, какие каталоги содержат сценарии сервера.
103+ # ScriptAliases по сути то же, что и Aliases(псевдонимы), за исключением того, что
104+ # документы в целевом каталоге рассматриваются как приложения и
105+ # запускается сервером по запросу, а не как документы, отправленные на
106+ # клиент. К директивам ScriptAlias применяются те же правила для завершающего символа "/",
107+ # что и к Alias.
108+ #
109+ ScriptAlias /cgi-bin/ "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/"
110+
111+Если вы поместите исполняемый файл с именем «mywebpage.cgi» в этот каталог, тогда к странице можно будет получить доступ как <http://localhost/cgi-bin/mywebpage.cgi> (или удаленно с соответствующим IP-адресом или доменным именем).
112+
113+Fcl-web с Lazarus в Windows создает файлы .exe. Чтобы Apache обслуживал эти файлы, вам необходимо добавить это:
114+
115+ AddHandler cgi-script .exe
116+
117+И чтобы обслуживать ваши исполняемые файлы из другого каталога, вы добавляете это:
118+
119+``` xml
120+ ScriptAlias /bin/ "C:/lazarus_projects/test-fclweb/bin/"
121+ <Directory "C:/lazarus_projects/test-fclweb/bin/">
122+ AllowOverride None
123+ Options None
124+ Order allow,deny
125+ Allow from all
126+ </Directory>
127+```
128+
129+### Форматирование HTML и читаемых полей запроса
130+
131+В предыдущем примере была показана простая HTML-страница. Можно, например, пожелать
132+
133+- динамически изменять вывод HTML-страницы и
134+- при чтении переменных, которые браузер передал веб-странице в полях запроса (например, в действиях HTTP GET и HTTP POST).
135+
136+Простое решение для первой проблемы - просто использовать стандартную подпрограмму Паскаля Format с добавлением %s или %d в файл HTML в соответствующие места, которые получат настраиваемое значение.
137+
138+### Чтение данных GET
139+
140+Чтобы прочитать переменные GET, можно использовать `ARequest.QueryFields`, который является потомком TStrings. Каждая переменная будет находиться в отдельной строке в TStrings в формате имя_переменной = значение, аналогично тому, как они отображаются в адресе страницы браузера. Для поиска определенной переменной можно использовать `ARequest.QueryFields.Values​​[]`, передав имя переменной в скобках, чтобы получить обратно ее значение, вместо ручного анализа строки.
141+
142+Итоговый код:
143+
144+``` pascal
145+procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;
146+ AResponse: TResponse; var Handled: Boolean);
147+var
148+ HexText, AsciiText: string;
149+begin
150+ HexText := ARequest.QueryFields.Values['hex'];
151+ AsciiText := HexToAnsii(HexText);
152+
153+ AResponse.ContentType := 'text/html;charset=utf-8';
154+ AResponse.Contents.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'mainpage.html');
155+ AResponse.Contents.Text := Format(AResponse.Contents.Text,
156+ [HexText, AsciiText]);
157+ Handled := True;
158+end;
159+```
160+
161+### Чтение данных POST
162+
163+Данные, отправленные запросами POST, можно получить из `TRequest.Content`. Он будет без заголовков запроса - другими словами, он будет содержать тело запроса.
164+
165+К отправленным данным формы также можно получить доступ с помощью `TRequest.ContentFields`, который представляет собой содержимое, проанализированное как поля, разделенные знаком `&` и декодированные. Например, следующий набор значений формы:
166+
167+`login: dfg 345&&`\
168+`login_senha: ====`\
169+`email: dfg`
170+
171+Будут преобразованы в 'APPLICATION/X-WWW-FORM-URLENCODED' следующим образом (см. [wikipedia POST (HTTP)](http://en.wikipedia.org/wiki/POST_%28HTTP%29)):
172+
173+`login=dfg+345%26%26&login_senha=%3D%3D%3D%3D&email=dfg`
174+
175+И будет доступно в `TRequest.ContentFields` через индекс строки или через свойство Values, что удобнее:
176+
177+`TRequest.ContentFields[0]: login=dfg 345&&`\
178+`TRequest.ContentFields[1]: login_senha=====`\
179+`TRequest.ContentFields[2]: email=dfg`\
180+`TRequest.ContentFields.Values['email']: dfg`
181+
182+Если используются другие типы mime, кроме 'MULTIPART/FORM-DATA' и 'APPLICATION/X-WWW-FORM-URLENCODED' (типы, поддерживаемые формами HTML):
183+
184+- контент доступен только в `TRequest.Content`, но не в `TRequest.ContentFields`
185+- использование этих mime-типов вызывает исключение для FPC 2.4.2 (исправлено в FPC 2.5+).
186+
187+Обратите внимание, что HTTP POST также может отправлять поля запроса (в URL-адресе), например <http://server/bla?question=how>, и к ним обращается `TRequest.QueryFields`, как описано в предыдущем разделе.
188+
189+``` pascal
190+procedure TFPWebModule1.DataModuleRequest(Sender: TObject; ARequest: TRequest;
191+ AResponse: TResponse; var Handled: Boolean);
192+var
193+ lData: String;
194+begin
195+ lData := ARequest.Content;
196+```
197+
198+### Чтение двоичных данных POST
199+
200+Загруженные файлы сохраняются во временном расположении с временным именем файла, чтобы сохранить файл, вы должны переместить его в постоянное расположение.
201+
202+Для получения данных на сервере, который был размещен, например, как multipart/form-data используйте что-то вроде этого:
203+
204+``` pascal
205+procedure TMainWebModule.TFPWebActions2Request(Sender: TObject;
206+ ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
207+var
208+ i: Integer;
209+begin
210+ // Обработать все полученные файлы
211+ for i := 0 to ARequest.Files.Count - 1 do
212+ begin
213+ // Настоятельно рекомендуется делать что-то еще, кроме Writeln ;)
214+ writeln ('Полученное имя файла: '+ARequest.Files[i].LocalFileName);
215+ end;
216+
217+ Handled := true;
218+end;
219+```
220+
221+Клиент может отправлять данные, например, FileFormPost.
222+
223+## Специализированные модули
224+
225+Класс *TFPWebModule* (используемый ниже) - это простой пример WEb-модуля, который можно использовать для всех видов HTTP-запросов.
226+
227+Однако fpweb поставляется с некоторыми специализированными модулями, которые имеют дополнительную поддержку для специализированных задач:
228+
229+- Класс **TSimpleFileModule** в модуле *fpwebfile.pp* можно использовать для отправки файлов. Вы указываете ему каталог, и он делает все остальное.
230+- Класс **TFPHTMLModule** в модуле *fphtml.pp* можно использовать для создания HTML.
231+- Класс **TProxyWebModule** в модуле *fpwebproxy.pp* - это готовый прокси для пересылки.
232+- Класс **TFPWebProviderDataModule** в модуле *fpwebdata.pp* обслуживает данные в формате JSON, которые могут использоваться хранилищами ExtJS.
233+- Класс **TSQLDBRestModule** в модуле *sqldbrestmodule.pp* реализует полноценный сервер REST, поддерживаемый SQLDB. См. Дополнительную информацию в [[SQLDBRestBridge]].
234+- Класс **TJSONRPCModule** в модуле *webjsonrpc.pp* реализует службу JSON-RPC.
235+- Класс **TExtDirectModule** в модуле *fpextdirect.pp* реализует вариант Ext.Direct службы JSON-RPC.
236+
237+## Использование нескольких модулей
238+
239+Если в веб-приложении только один модуль, все запросы будут направлены в этот модуль.
240+
241+По мере роста вашего веб-приложения можно использовать несколько модулей. Новый модуль можно добавить, выбрав 'File - New', а затем один из 'Web module' или 'HTML Web Module'.
242+
243+FCL-web использует URL-адрес, чтобы определить, как следует обрабатывать HTTP-запрос. Поэтому он должен знать, какие веб-модули существуют в приложении. Для этого каждый модуль должен быть зарегистрирован.
244+
245+Каждый модуль регистрируется в fcl-web в разделе инициализации модуля, в котором он определен:
246+
247+``` pascal
248+RegisterHTTPModule('location', TMyModule);
249+```
250+
251+Затем модуль будет вызван, если используется URL-адрес формы
252+
253+`http://www.mysite.org/mycgi.cgi/location`
254+
255+или
256+
257+`http://www.mysite.org/mycgi.cgi?module=location`
258+
259+Если присутствует несколько модулей, имя модуля должно появиться в URL-адресе, в противном случае возникнет ошибка.
260+
261+Это поведение также можно принудительно настроить для приложений, которые имеют только один модуль, установив для свойства приложения AllowDefaultModule значение false:
262+
263+``` pascal
264+Application.AllowDefaultModule := False;
265+```
266+
267+В этом случае приложение fcl-web всегда будет требовать имя модуля в URL-адресе.
268+
269+Имя переменной запроса, определяющей имя модуля (по умолчанию это 'module'), можно задать в свойстве `Application.ModuleVariable`. Следующий код
270+
271+``` pascal
272+Application.ModuleVariable := 'm';
273+```
274+
275+гарантирует, что следующий URL-адрес будет направлен в TMyModule:
276+
277+`http://www.mysite.org/mycgi.cgi?m=location`
278+
279+Если всего этого недостаточно для определения модуля, которому следует передать запрос, можно использовать событие `Application.OnGetModule`. Это тип `TGetModuleEvent`:
280+
281+``` pascal
282+type
283+ TGetModuleEvent = Procedure (Sender : TObject; ARequest : TRequest;
284+ Var ModuleClass : TCustomHTTPModuleClass) of object;
285+```
286+
287+Создание обработчика событий для этого события позволяет точно контролировать модуль, созданный для обработки запроса: запрос (переданный в ARequest) может быть исследован, а для переменной 'ModuleClass' должен быть задан класс модуля, который должен обрабатывать Запрос.
288+
289+Если 'ModuleClass' при возврате равен 'Nil', в браузер будет отправлено сообщение об ошибке.
290+
291+## Использование Actions
292+
293+Модуль можно использовать для группировки определенных видов действий, которые логически связаны друг с другом. Представьте себе модуль TUserModule, который используется для управления пользователями на веб-страницах. С пользователем может быть связано несколько действий:
294+
295+- Создание
296+- Удаление
297+- Редактирование
298+- Отображение
299+
300+Эти разные действия могут обрабатываться одним и тем же модулем. Можно определить действие по URL-адресу вручную, например:
301+
302+`http://mysite/mycgi.cgi/user?action=delete&id=12`
303+
304+Это можно автоматизировать.
305+
306+Для упрощения разделения различных действий в модуле есть свойство actions: это коллекция, в которой каждый элемент связан с различным ответом на запрос. Действия имеют различные свойства:
307+
308+Name
309+Название действия. URL-адрес будет проверен, чтобы определить название действия.
310+
311+Content
312+строка. Если задано, оно отправляется в браузер.
313+
314+Contents
315+список строк. Если задано, оно отправляется в браузер.
316+
317+ContentProducer
318+если задано, ContentProducer будет обрабатывать запрос.
319+
320+Default
321+если установлено значение «True», это действие является действием по умолчанию. Это означает, что если FCL-Web не может определить имя действия, будет выполнено это действие.
322+
323+Template
324+если установлено, этот шаблон будет обработан, а результаты отправлены в браузер.
325+
326+Также есть некоторые события:
327+
328+BeforeRequest
329+выполняется до обработки запроса. Может использоваться для установки 'Content' или других свойств.
330+
331+AfterRequest
332+выполняется после обработки запроса.
333+
334+OnRequest
335+обработчик событий для обработки запроса. Если задано, обработчик используется для обработки запроса.
336+
337+Опять же, как и в случае нескольких модулей, URL-адрес используется для определения того, какое действие выполнить. Используется часть сразу после части модуля (в данном примере "user"):
338+
339+`http://mysite/mycgi.cgi/user/delete&id=12`
340+
341+выполнит действие под названием 'delete'.
342+
343+Свойство 'ActionVar' модуля можно использовать для установки имени используемой переменной запроса. Настройка
344+
345+``` pascal
346+UserModule.ActionVar := 'a';
347+```
348+
349+может использоваться для изменения указанного выше URL на
350+
351+`http://mysite/mycgi.cgi/user?a=delete&id=12`
352+
353+Если в приложении только один модуль, URL-адрес можно сократить до
354+
355+`http://mysite/mycgi.cgi/delete&id=12`
356+
357+## Использование HTML-шаблонов
358+
359+Информацию об использовании шаблонов, тегов шаблонов и параметров тегов шаблонов для создания страниц ответов см. в файле fptemplate.txt в каталоге FPC в /packages/fcl-base/texts/.
360+
361+Примеры проектов, демонстрирующих использование шаблонов, можно найти в каталоге FPC в /packages/fcl-web/examples/fptemplate/ (дополнительные сведения см. в README.txt). (В более ранних версиях эти примеры находились в каталоге Lazarus в /components/fpweb/demo/fptemplate/)
362+
363+## Советы и устранение неполадок
364+
365+### Отправка кодов результатов
366+
367+Чтобы отправить HTTP-ответ, отличный от 200 OK, используйте **AResponse.Code** и **AResponse.CodeText**, например
368+
369+``` pascal
370+AResponse.Code := 404;
371+AResponse.CodeText := 'Document not found';
372+```
373+
374+### Отправка двоичных данных
375+
376+Подход, который, кажется, работает для отправки, например, файл tiff с веб-сервера на клиент - адаптированный из \$(fpcdirectory)\packages\fcl-web\examples\jsonrpc\demo1\wmdemo.pp - что-то вроде:
377+
378+``` pascal
379+AResponse.ContentStream := TMemoryStream.Create;
380+
381+try
382+ AResponse.ContentStream.LoadFromFile('/tmp/sample.tiff');
383+ AResponse.ContentType := 'image/tiff'; //или любой другой тип MIME, который вы хотите отправить
384+ //что делать: есть пример fpweb, который получает тип mime из расширения файла ...
385+ AResponse.ContentLength:=AResponse.ContentStream.Size; //видимо не происходит автоматически?
386+ AResponse.SendContent;
387+finally
388+ AResponse.ContentStream.Free;
389+end;
390+
391+Handled := true;
392+```
393+
394+### Error: Could not determine HTTP module for request
395+
396+У вас может быть несколько модулей и несколько actions. Если вы укажете URL-адрес только с 1 элементом, например:
397+
398+```html4strict
399+http://localhost/cgi-bin/somemodule
400+```
401+
402+тогда fpweb предполагает, что вы указываете действие. Если у вас не установлен модуль по умолчанию, вы получите внутреннюю ошибку сервера 500 (не удалось определить модуль HTTP для запроса)
403+
404+Вы можете изменить это поведение, чтобы вместо этого fpweb отображал имя модуля, установив для свойства приложения `PreferModuleName` значение `true`.
405+
406+### Error: response code 500 Internal Server error when trying to handle DELETE method
407+
408+В FPC 2.6.2 и ниже fcl-web не принимает метод DELETE и выдает ошибку.
409+
410+### fpWeb/FCGI и Apache 2.4 (режим mod_proxy_fcgi)
411+
412+1, Enable following modules: setenvif_module, proxy_module and proxy_fcgi_module\
413+(on CentOS 7 modules are defined in file /etc/httpd/conf.modules.d/00-base.conf and /etc/httpd/conf.modules.d/00-proxy.conf). Если вы хотите развернуть приложение FCGI позади прокси-сервера Apache 2.4+, вам понадобится переменная PATH_INFO в заголовках, которые отправляются через сокет демону FCGI.
414+
415+1\. Включите следующие модули: setenvif_module, proxy_module и proxy_fcgi_module\
416+(в CentOS 7 модули определены в файлах /etc/httpd/conf.modules.d/00-base.conf и /etc/httpd/conf.modules.d/00-proxy.conf).
417+
418+ LoadModule setenvif_module modules/mod_setenvif.so
419+ LoadModule proxy_module modules/mod_proxy.so
420+ LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
421+
422+2\. Конфигурация обратного прокси для fpWeb/FCGI, прослушивающего порт 9000.\
423+\$1 = module name\
424+\$2 = action name
425+
426+ SetEnvIf Request_URI . proxy-fcgi-pathinfo=full
427+ ProxyPassMatch "/fcgi/(.*)/(.*)" "fcgi://127.0.0.1:9000/$1/$2"
428+
429+### fpWeb/FCGI и nginx
430+
431+Для правильной маршрутизации fcl-web требует переменную PATH_INFO в заголовках, отправленных из nginx. Для этого вы должны разделить весь URL-адрес на имя приложения FastCGI и часть информации о пути с помощью оператора конфигурации *fastcgi_split_path_info*. Оператор принимает регулярное выражение и помещает второе совпадение в конфигурационную переменную *\$fastcgi_path_info*. Эту переменную можно передать вашему приложению с помощью оператора *fastcgi_param*.
432+
433+Следующий пример конфигурации включает в себя полноценный виртуальный хост для nginx, который передает все из *<http://myserver:8080/mycgiapp/>* во внешнее приложение FastCGI.
434+
435+ server {
436+
437+ listen 8080;
438+ listen [::]:8080;
439+
440+ server_name _;
441+
442+ root "/var/www";
443+
444+ location /mycgiap/ {
445+ # setting up PATH_INFO
446+ fastcgi_split_path_info ^(/mycgiapp/)(.*)$;
447+ fastcgi_param PATH_INFO $fastcgi_path_info;
448+
449+ # other parameters
450+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
451+ fastcgi_param QUERY_STRING $query_string;
452+ fastcgi_param REQUEST_METHOD $request_method;
453+ fastcgi_param CONTENT_TYPE $content_type;
454+ fastcgi_param CONTENT_LENGTH $content_length;
455+ fastcgi_param SCRIPT_NAME $fastcgi_script_name;
456+ fastcgi_param REQUEST_URI $request_uri;
457+ fastcgi_param DOCUMENT_URI $document_uri;
458+ fastcgi_param DOCUMENT_ROOT $document_root;
459+ fastcgi_param SERVER_PROTOCOL $server_protocol;
460+ fastcgi_param REQUEST_SCHEME $scheme;
461+ fastcgi_param HTTPS $https if_not_empty;
462+ fastcgi_param GATEWAY_INTERFACE CGI/1.1;
463+ fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
464+ fastcgi_param REMOTE_ADDR $remote_addr;
465+ fastcgi_param REMOTE_PORT $remote_port;
466+ fastcgi_param SERVER_ADDR $server_addr;
467+ fastcgi_param SERVER_PORT $server_port;
468+ fastcgi_param SERVER_NAME $server_name;
469+
470+ # pass requests to your FastCGI application
471+ fastcgi_pass 127.0.0.1:9000;
472+ }
473+ }
474+
475+## Примечание
476+
477+- Модуль cgiapp устарел, по возможности используйте fpcgi.
478+
479+- Модули fastcgi, custfcgi и fpfcgi не поддерживаются в Darwin в настоящее время, потому что он использует другой механизм, чем опция MSG_NOSIGNAL для recv(), чтобы указать, что SIGPIPE не должен генерироваться в случае разрыва соединения. См. <http://lists.apple.com/archives/macnetworkprog/2002/Dec/msg00091.html>, чтобы узнать, как это исправить.
480+
481+- Если вы развертываете свое приложение CGI и получаете такие ошибки, как "Error: No action name and no default action", вы должны убедиться, что для URL-адреса назначено действие, или перехватить неподдерживаемые действия с действием, отмеченным по умолчанию. В обоих случаях следует использовать обработчик события `OnRequest` для действия, которое устанавливает `Handled:=true`.
482+
483+## См. также
484+
485+- [[fpWeb Tutorial]]
486+- [[fphttpclient]] - Часть fcl-web, которую можно использовать отдельно в клиентских приложениях
487+- *write me!* fphttpserver - Небольшой автономный веб-сервер Object Pascal. Может использоваться для обслуживания приложений fcl-web CGI.
488+- [[CGI Web Programming|CGI_Web_Programming#Debugging_CGI]] Информация об отладке приложений CGI
489+- [Часть учебника Leonardo Ramé](https://github.com/leonardorame/Ext4-MVC-Tutorial/wiki/Lazarus-Server), в котором показано, как писать приложение fcl-web CGI; включает пример создания содержимого JSON
490+
491+---
492+*From the Free Pascal wiki, page "fcl-web/ru", as it stood on 2021-01-07 after a change by Zoltanleo, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history