Nach längerer Blog Pause schreibe ich über die Implementierung eines Datei Upload mittels POST nach dem RFC1867. Das Vorgehen beim Datei Upload auf der Server Seite wird im Netz oft publiziert. Eine Beschreibung eines Upload Vorgang von der Client Seite aus findet jedoch wenig Verbreitung im Netz. Ich versuche meine Beschreibung möglichst allgemein zu halten. Desweiteren weiß ich das von der hier verwendeten Programmiersprache Ruby kaum Unterschiede zu Perl oder PHP bestehen. Alle genannten Sprachen bieten HTTP Client Funktionalitäten. Folgend ein Script und die Vorgehensweise nach RFC1867 im Detail.
#! /usr/bin/ruby ## HTTP Klasse einbinden require 'net/http' ## Anfrageninstanz erstellen http = Net::HTTP.new('example.com', 80) ## Das Timeout festlegen (So lange wartet das Script bis der Server nach einer Anfrage antwortet) http.read_timeout = 100 ## Eine zufällige Nummer die zum separieren des Anfragen Inhalts verwendet wird. ## Dieser String darf im Anfrage String vorkommen. luckynumber = rand(9999999999).to_s(); ## Die HTTP Header der Anfrage. ## Wichtig ist hierbei den Content-Type entsprechend zu setzen. (multipart/form-data; nicht www-urlencoded) ## luckynumber der Wert hinter boundary= ist hierbei die Variable die zur Trennung von Inhalten verwendet wird. header = { 'User-Agent' => 'Mozilla/5.0 (en-US) Gecko/20100303' 'Content-Type' => 'multipart/form-data; boundary=luckynumber'+luckynumber } ## Die Daten die an den Webserver gesendet werden. ## Der Platzhalter *Inhalt der Datei in dem nicht luckynumber123456789 vorkommt* muss durch deinen Datei Inhalt ersetzt werden. ## --luckynumber"+luckynumber wird als Seperator der Datei verwendet. ## Die Kopdaten der Datei, Dateiname und Dateicodierung, müssen mit zwei ## Umbrüchen (\n\n) vom Inhalt separiert werden. data = "--luckynumber"+luckynumber+" Content-Disposition: form-data; name=\"Filedata\"; filename=\"dateiname.txt\" Content-Type: text/plain *Inhalt der Datei in dem nicht luckynumber123456789 vorkommt* --luckynumber"+luckynumber+"-- " ## Absenden der HTTP POST Dateiupload-Anfrage resp = http.post('upload.php', data, header) ## Von der Anfrage erhalten wir die Angefragten Daten und ## einen Status Code. Ist der Status Code ungleich 200 ## ist ein Fehler aufgetreten. if resp.code != "200" puts '# An error has occurred...' endif
Die Ruby interne Net/HTTP Klasse wird für die Socketarbeiten für das Script verwendet. Die Anfragen werden über diese Ruby standard Klasse versandt. Der im Kopf Bereich angegebene Separator (boundary=) darf nicht zufällig im String der Anfrage vorkommen.
Allgemein ist es wichtig die Anfrage multipart/form-data; Formatiert zu übertragen. Im Kopf Bereich der HTTP-Anfrage der gesandt wird ist dabei diese Zeichenkette ausschlaggebend:
Content-Type: multipart/form-data; boundary=luckynumber123456789
Bei den Daten in der Anfrage ist zu beachten das einzelne Werte mit Hilfe eines Strings separiert werden. Hier nochmals “luckynumber123456789″ als seperator.
--luckynumber123456789 Content-Disposition: form-data; name="Filedata"; filename="dateiname.txt" Content-Type: text/plain *Inhalt der Datei in dem nicht luckynumber123456789 vorkommt* --luckynumber123456789--
Ein Plain-Text Beispiel für den Inhalt einer Anfrage-Zeichenkette. Die Content-Type Angabe übermittelt den Mime-Typ der Datei. Eine alphabetisch sorierte Liste der Mime-Typen findest du hier. Weitere HTTP Fehler Codes zum auswerten von HTTP-Response Codes findest du hinter diesem Link.
Viel Freude beim Dateien Uploaden nach RFC1867.
Da die Statistik sehr viele Suchanfragen nach dem oben betitelten Thema verzeichnet, habe ich mich entschlossen darüber zu schreiben. Allgemein ist “Javascript: prüfen ob ein Element existiert” ein gutes Google Thema. In Javascript ist das prüfen ob ein Element existiert bzw. vorhanden ist ebenso einfach wie in jQuery. Zum Javascriptcode:
if (document.getElementById('divname')) { // Code ausführen, wenn DIV Element vorhanden. Funktioniert! }
Der Selektor ist in purem Javascript auf die div id beschränkt. Sehr ärgerlich ist das hierbei keine Klassen selektiert werden können. jQuery bietet diese Möglichkeit.
Öfter habe ich nun schon im Web gelesen, das Beispielcode gesucht wird, wie es in C# möglich ist eine Internetseite als Rückgabewert einer Methode als String zurück zu erhalten. Ich verwende hierbei die Klasse WebRequest für die HTTP Anfrage und den Streamreader zum lesen des Ergebnisses. Folgender, gut kommentierter, Codeschnippsel den ich für ein kleines Projekt erstellt habe sollte dir weiterhelfen:
/* * [url = string] die URL * [buffersize = int] Größe des Zwischenspeichers */ private static string http_get_as_string(string url, int buffersize) { // Initialisiert den Webrequest WebRequest request = WebRequest.Create(url); // Der Anfragentyp. Wir übertragen keine POST Daten request.Method = "GET"; // Sollte keine nach 10000 Millisekunden keine Antwort kommen abbrechen request.Timeout = 10000; // Fehler Abfangen für den Fall das keine Antwort kommt try { // Die Antwort des Webservers erhalten HttpWebResponse response = (HttpWebResponse) request.GetResponse(); // Gibt den Datenstream der Antwort zurück Stream resource = response.GetResponseStream(); // Den Zwischenspeicher erstellen byte[] buffer = new byte[buffersize]; // Hier wird gespeichert wie viel Bytes noch zu lesen sind int toread = 0; // Der Inhalt der Internetseite string content = ""; // Der Einlesevorgang in einer Schleife. Stück für Stück. Solange noch Daten vorhanden sind do { // Lesen aus dem Stream. Maximal die Zwischenspeichergröße auf einmal toread = resource.Read(buffer, 0, buffersize); // Prüft ob noch Daten zum Codieren da sind if (toread != 0) { // Daten UTF-8 codieren content += Encoding.UTF8.GetString(buffer, 0, toread); } } while(toread > 0); return content; } catch (WebException e) { return ""; } }
Die Funktion ermöglicht nicht nur das einlesen von HTML Code sondern ebenso das einlesen von XML, CSS oder Javascript Datein. Kurzum alle Dateien die über HTTP erreichbar sind. Für Fragen steht die Kommentarfunktion zur Verfügung.
Ich stand vor kurzem vor dem Problem in Javascript zu prüfen ob ein DIV Element in einem HTML Dokument existiert. Mir stand aus vorangehender Entwicklung das jQuery Framework zur Verfügung. Dabei produzierte ich folgenden Code:
if ($('div#divname')) { // Code ausführen, wenn DIV Element vorhanden. Funktioniert leider nicht }
Das klappte leider nicht, da der Einsatz der jQuery Selektor Funktion immer ein Objekt zurückliefert. Mir war klar das es sich hierbei um ein leeres Objekt handelt und ich nur auf die Länge prüfen müsste. Sollte die Länge 0 sein ist der DIV im aktuellen Dokument nicht vorhanden. Hier nun der Code mit dem es entgültig klappte:
if ($('div#divname').length > 0) { // Code ausführen, wenn DIV Element vorhanden. Funktioniert! }
Ich verwende > anstatt ==, da diese Methode auch bei CSS Klassen funktioniert und keine Nachteile in der Performance bietet. Klassen können mehrfach im Dokument vorkommen. Deswegen kann die Länge größer als 1 sein.
Mehr zum Thema jQuery Selektoren

