Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#12

AW: Wie / Womit werden Webanwendungen designt ?

  Alt 14. Jan 2014, 16:16
Von Codegear/Emba gibt es auch "Delphi for PHP" bzw. RadPHP und HTML5 Builder.



Ganz "billig" geht auch TidHTTPServer.

HTML-Datei ausgeben und dann entsprechend die GET/POST-Daten auswerten.



z.B.: Ein billiger File-Server, welcher eine HTML-Webseite und Zusatzdateien ausliefert.

Das hatte ich mir implementiert:
- OnCommandGet (GET)
- OnException
- OnListenException

geht auch:
- OnCommandOther (POST?)
- und dazu dann noch eine Authentifizierungs- und Session-Behandlung (für ein Login der Benutzer)


So wie bei HTMLPath = 'info' kann man auf bestimmte URLs aka "Befehle" reagieren und dort entsprechende Webseiten ausliefern.
Und ansonsten werden die Dateien in einem bestimmten Verzeichnis (Path_Help) ausgeliefert. (Bilder, CSS, JS, hartcodierte HTML-Seiten usw.)
In die HTML-Dateien kommen dann noch ein paar Formulare, welche z.B. via POST ihre Daten übertragen (an einen entsprechende URL/Befehl)
Das HTML kann im Programm dynamisch zusammengesetzt werden, wofür es auch entsprechende Frameworks gibt, oder es kommt aus externen Dateien/Resourcen und da werden per StringReplace eventuell noch ein paar Platzhalter aufgefüllt.

Delphi-Quellcode:
procedure TMyService.HTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
const
  // http://de.selfhtml.org/diverses/mimetypen.htm
  FileExt: array[0..7] of string = ('', '.txt', '.html', '.css', '.js', '.gif', '.jpeg', '.png');
  ContentType: array[0..7] of string = ('application/octet-stream', 'text/plain', 'text/html', 'text/css', 'text/js', 'image/gif', 'image/jpeg', 'image/png');
var
  HTMLPath: string;
begin
  try
    HTMLPath := ARequestInfo.Document;
    while (HTMLPath <> '') and CharInSet(HTMLPath[1], ['/', '\', '.', ':']) do
      Delete(HTMLPath, 1, 1);
    if HTMLPath = 'infothen begin
      LogEvent('WebServer-Get 200: ' + ARequestInfo.URI + ' => ' + ARequestInfo.From);
      AResponseInfo.ContentType := 'text/plain';
      AResponseInfo.ResponseNo := 200;
      AResponseInfo.ResponseText := 'OK';
      AResponseInfo.ContentText := 'ServiceName: ' + DataServer1.ServiceName + #10
                                  + 'ServicePath: ' + ParamStr(0) + #10
                                  + 'ServerName: ' + TDSServerMethods(nil).ServerComputerName + #10 // geht, da ServerComputerName auf nichts einer TDSServerMethods-Instanz zugreift
                                  + #10
                                  + 'HelpName: ' + HTTPServer1.ServerSoftware + #10
                                  + 'HelpPort: ' + IntToStr(HTTPServer1.DefaultPort) + #10
                                  + 'HelpPath: ' + Path_Help + #10;
    end else if (Trim(HTMLPath) = '') or (TPath.GetExtendedPrefix(HTMLPath) <> TPathPrefixType.pptNoPrefix) or not TPath.HasValidFileNameChars(HTMLPath, False) then begin
      LogEvent('WebServer-Get 403: ' + ARequestInfo.URI + ' => ' + ARequestInfo.From);
      AResponseInfo.ContentType := 'text/plain';
      AResponseInfo.ResponseNo := 403;
      AResponseInfo.ResponseText := 'Forbidden';
      AResponseInfo.ContentText := '403 Forbidden'#10#10 + HTMLPath;
    end else if not FileExists(Path_Help + HTMLPath) then begin
      LogEvent('WebServer-Get 404: ' + ARequestInfo.URI + ' => ' + ARequestInfo.From);
      AResponseInfo.ContentType := 'text/plain';
      AResponseInfo.ResponseNo := 404;
      AResponseInfo.ResponseText := 'Not Found';
      AResponseInfo.ContentText := '404 Not Found'#10#10 + HTMLPath;
    end else begin
      LogEvent('WebServer-Get: ' + ARequestInfo.URI + ' => ' + ARequestInfo.From);
      AResponseInfo.ContentType := ContentType[Max(IndexText(ExtractFileExt(HTMLPath), FileExt), 0)];
      AResponseInfo.ResponseNo := 200;
      AResponseInfo.ResponseText := 'OK';
      AResponseInfo.ContentStream := TFileStream.Create(Path_Help + HTMLPath, fmOpenRead or fmShareDenyWrite); // Daten
      AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size; // Datenmenge
      AResponseInfo.CacheControl := 'public'; // Browsercache verwenden
      AResponseInfo.Date := TFile.GetLastWriteTime(Path_Help + HTMLPath); // Änderungsdatum
      AResponseInfo.ETag := Format('%d_%.5f', [AResponseInfo.ContentLength, AResponseInfo.Date]); // (billiger) Hash
    end;
  except
    on E: Exception do begin
      LogEvent('WebServer-Get-Error: ' + ARequestInfo.URI + ' => ' + ARequestInfo.From + sLineBreak + E.ClassName + ': ' + E.Message);
      AResponseInfo.ContentType := 'text/plain';
      AResponseInfo.ResponseNo := 500;
      AResponseInfo.ResponseText := 'Internal Error';
      AResponseInfo.ContentStream.Free;
      AResponseInfo.ContentStream := nil;
      AResponseInfo.ContentLength := 0;
      AResponseInfo.ContentText := '500 Internal Error'#10#10 + E.ClassName + ': ' + E.Message + #10#10 + HTMLPath;
      AResponseInfo.CacheControl := '';
      AResponseInfo.Date := 0;
      AResponseInfo.ETag := '';
    end;
  end;
end;
$2B or not $2B

Geändert von himitsu (14. Jan 2014 um 16:19 Uhr)
  Mit Zitat antworten Zitat