4 Stimmen

Wie kann ich in ColdFusion den Inhalt des übermittelten Formulars extrahieren und speichern?

Ich schreibe eine Anwendung in ColdFusion, und auch wenn es meist stabil ist, es Fehler so oft. Da sie die alte Anwendung bereits ersetzt hat, sind es manchmal die Benutzer, die Fehler bekommen, anstatt ich.

Ich habe eine nette Seite erstellt, die bei Fehlern angezeigt wird und Informationen an mich sendet, z. B. Fehler, Referrer, Fehler auf welcher Seite, Zeilennummer usw.

Das Einzige, was ich nicht zum Funktionieren bringen kann, ist die Übermittlung der Formulardaten, falls es welche gibt. Ich weiß nicht, welche Seite es auf vorher fehlgeschlagen, so kann ich nicht nur Ausgabe '#form.field#'.

Zum Beispiel wenn:

form.abc = 1
form.def = 2

Wie kann ich die Variablennamen und -werte von "form" erhalten, ohne sie vorher zu kennen?

Ist dieses Dokument zur Schleifenbildung über eine Struktur irgendwo auf dem richtigen Weg?

Außerdem suche ich nach einer guten Möglichkeit, diese Daten in einer Datenbank zu speichern, denn dort werden auch die anderen Informationen über den Fehler gespeichert, und ich möchte sie nicht unbedingt in eine E-Mail an mich schreiben müssen.

7voto

Peter Boughton Punkte 105921

Der Bereich Formular hat eine FieldNames die Ihnen mitteilt, welche Felder übermittelt wurden.

Sie können auch Folgendes tun StructKeyList(Form) um eine Liste der aktuellen Variablen im Bereich zu erhalten. Diese enthält auch FieldNames und alle anderen Variablen, die seither zum Bereich "Form" hinzugefügt wurden.

Beide können innerhalb einer <cfloop index="CurField" list="#StructKeyList(Form)#"> - aber es gibt einfachere Wege...

Wenn Sie mit CF8 arbeiten, können Sie den Bereich ganz einfach in einen String umwandeln mit serializeJson() y deserializeJson() Funktionen, die dann in einem geeigneten Datenbankfeld gespeichert werden können.

Wenn Sie mit CF6..7 arbeiten, können Sie eine CFC namens cfjson von riaforge das diese Funktionen nachahmt.

Schließlich, wenn Sie auf früheren Versionen von CF, oder haben eine seltsame Abneigung gegen die Verwendung von JSON für die Speicherung, können Sie Ihre eigenen mit einem noch einfacher Schleife, um die oben angedeutet - eine Sammlung Schleife können Sie direkt durch eine Struktur oder Scope - beachten Sie, dass einige ärgerlich Person gewählt "Element" statt "Index" als Attribut für diese.

Da wir wissen, dass die Formularvariablen alle einfache Objekte (d.h. Strings) sind, habe ich mich für eine einfache key=value[newline]key=value[newline]... Format, das auch leicht umkehrbar ist.

Kodierung:

<cfset Output = '' />
<cfloop item="CurField" collection="#Form#">
    <cfset Output = Output & CurField & '=' & Form[CurField] & Chr(10) />
</cfloop>

<cfoutput>#Output#</cfoutput>

Entschlüsselung:

<cfset FormData = StructNew()/>
<cfloop index="CurLine" list="#Output#" delimiters="#Chr(10)#">
    <cfset FormData[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') />
</cfloop>

<cfdump var="#FormData#"/>

Ein letzter wichtiger Hinweis: Wie bei allen vom Benutzer bereitgestellten Variablen (Form,Url,Cookie scopes) müssen Sie sicherstellen, dass Sie diese korrekt behandeln, um Sicherheitslücken zu vermeiden - insbesondere stellen Sie sicher, dass Sie cfqueryparam verwenden für todo Ihre Datenbankabfragen - Ich möchte nicht zu weit abschweifen, aber Sie können gerne eine weitere Frage stellen, wenn Sie Hilfe zu cfqueryparam benötigen.

Ich hoffe, das hilft. :)

4voto

Adam Tuttle Punkte 19429

Wenn Sie manuell über alle Formularfelder iterieren wollen, ist die einfachste Methode eine cfloop wie diese:

<cfloop collection="#form#" item="variables.name">
  #variables.name#=(#form[variables.name]#)<br/>
</cfloop>

Für die Zwecke einer Fehler-E-Mail ist es jedoch wahrscheinlich einfacher, den Formularbereich (der nur eine spezielle Struktur ist) wie folgt zu "dumpen":

<cfmail
  from="errors@#cgi.server_name#"
  to="you@yourdomain.com"
  subject="Error Occurred in such and such a place"
  type="html">
    <cfdump var="#form#"/>
</cfmail>

Wenn ich Fehler-E-Mails versende, füge ich gerne eine zweite cfdump für den CGI-Bereich (wiederum nur eine spezielle Struktur), da diese einige andere hilfreiche Informationen über die Anfrage liefern kann.

Wenn Sie CF 8 haben, können Sie auch im Textformat dumpen, wie z. B. im folgenden, weil dadurch die Nachricht kleiner wird (und meiner Meinung nach besser lesbar ist)

<cfdump var="#form#" format="text">

Anmerkung: Die format Attribut des CFDump-Tags wurde für CF 8 hinzugefügt, so dass Sie es in früheren Versionen von ColdFusion nicht mehr verwenden können.

Sie haben erwähnt, dass Sie nach einer Möglichkeit gesucht haben, diese Fehler in einer Datenbank zu speichern, und das ist eine gute Idee. Anstatt eine eigene Lösung dafür zu entwickeln, schlage ich vor, dass Sie sich Folgendes ansehen BugLogHQ . Es gibt sie schon eine Weile und sie funktioniert gut für andere, mich eingeschlossen, und das Beste ist, sie ist KOSTENLOS und Open Source. Sein Alter und seine weite Verbreitung bedeuten, dass es weniger wahrscheinlich ist, Fehler in seinem eigenen Code zu haben, und dass es wahrscheinlich mehr und bessere Funktionen hat als das, was Sie schreiben würden.

Mit BugLogHQ müssen Sie sich nicht um die Anzeige des Fehlers kümmern, Sie senden einfach die Daten an den Bug Logger und dieser erledigt den Rest.

3voto

Pete Jordan Punkte 548

Form ist nur eine Hash-Struktur, so dass Sie einfach durch die Schlüssel iterieren können:

<cfoutput>
 <cfloop collection=#form# item="field">
  #htmleditformat(field)=#htmleditformat(form[field])#<br/>
 </cfloop>
</cfoutput>

Eingabe der Daten in eine Datenbank? Wie Sie das machen, hängt davon ab, was Sie anschließend damit machen wollen. Die flexibelste Lösung könnte darin bestehen, einfach die gesamte form (und url ) in ein WDDX-Objekt und speichern dieses in einem Blob-Feld:

<cfwddx action="cfml2wddx" input=#url# output="encodedURL"/>
<cfwddx action="cfml2wddx" input=#form# output="encodedForm"/>
<cfquery datasource="yourDSN">
 INSERT INTO errorlog (datestamp, event, script_name, path_info, url, form)
 VALUES
  (<cfqueryparam value=#now()# cfsqltype="CF_SQL_TIMESTANP"/>,
   <cfqueryparam value="your error string or cfcatch data" cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.script_name# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.path_info# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#encodedURL# cfsqltype="CF_SQL_BLOB"/>,
   <cfqueryparam value=#encodedForm# cfsqltype="CF_SQL_BLOB"/>)
</cfquery>

Auf diese Weise haben Sie Zugang zu allen Rohdaten, die Sie in aller Ruhe analysieren können. Es gibt natürlich auch viele andere Möglichkeiten.

3voto

rip747 Punkte 9207

Wenn Sie die Application.cfc in Ihrer Anwendung verwenden, ersetzen Sie einfach die onError-Methode durch die unten stehende. Hinweis: application.settings.mode kann einer der folgenden Werte sein (dev,test,prod). application.settings.webmasteremail sollte auf die E-Mail-Adresse gesetzt werden, an die die Fehlerinformationen gesendet werden sollen. Diese beiden Variablen sollten in der Methode onApplicationStart gesetzt werden.

Wozu dient diese Funktion? Wenn die Anwendung auf den Modus "dev" eingestellt ist (durch Setzen von application.settings.mode = "dev"), werden die Fehlerinformationen auf dem Bildschirm angezeigt. Ist die App auf einen anderen Modus eingestellt (wie test oder prod), sendet sie eine E-Mail und speichert die Informationen in einer Datenbank.

<cffunction name="onError" returnType="void" output="true">
    <cfargument name="exception" required="true">
    <cfargument name="eventname" type="string" required="true">
    <!--- corrects bug where <cfabort> throw an error --->
    <cfif arguments.exception.rootCause eq "coldfusion.runtime.AbortException">
        <cfreturn>
    </cfif>
    <cfsavecontent variable="errordata">
        <p>#eventname#</p>
        <cfdump var="#exception#" label="Exception Information" format="text">
        <cfdump var="#url#" label="URL Information" format="text">
        <cfdump var="#form#" label="FORM Information" format="text">
        <cfdump var="#application#" label="Application Scope" format="text">
        <cfif isdefined("session")>
            <cfdump var="#session#" label="Session Scope" format="text">
        </cfif>
        <cfif isdefined("client")>
            <cfdump var="#client#" label="Client Scope" format="text">
        </cfif>
        <cfdump var="#cgi#" label="URL Information" format="text">
    </cfsavecontent>

    <!--- will email the error inforation and display the error page --->
    <cfif application.settings.mode eq "dev">
        <p>#eventname#</p>
        #errordata#
    <cfelse>
        <cfmail to="#application.settings.webmasteremail#" from="error@#cgi.http_host#" subject="Error has occured on #cgi.http_host#" type="HTML" charset="windows-1252">
        <p>#eventname#</p>
        #errordata#
        </cfmail>

        <cfquery datasource="yourDSN">
        insert into errorlog
        (
            creationdate
            ,event
            ,info
        )
        values
        (
            <cfqueryparam value="#now()#" cfsqltype="CF_SQL_TIMESTAMP"/>
            ,<cfqueryparam value="#eventname#" cfsqltype="CF_SQL_VARCHAR"/>
            ,<cfqueryparam value="#errordata#" cfsqltype="CF_SQL_LONGVARCHAR"/>
        )
        </cfquery>

        <h2>A functional error has occurred.</h2>
        <p>A notification of this error has been automatically e-mailed to the development team; no action on your part is required.</p>
        <p>Please click the "back" button on your browser to return to the web site.  We apologize for this inconvenience.</p>
    </cfif>
</cffunction>

0voto

Nathan Strutz Punkte 7890

Wenn Sie sich die Formularvariablen per E-Mail zuschicken, geben Sie sie einfach so aus:

<cfmail type="html" ...>
    <cfdump var="#form#" label="form">
    <cfdump var="#cgi#" label="cgi">
    <cfdump var="#session#" label="session">
</cfmail>

Sie können dort jeden beliebigen Bereich auslagern, den Sie möchten. Sie können die von mir zur Verfügung gestellten brauchen oder auch nicht.

Sie sagten, Ihr anfängliches Problem war, dass die Anwendung die alte Anwendung ersetzt? Entwickeln Sie auf demselben Server, auf dem Sie die Anwendung bereitstellen? Wenn ja, können Sie einfach den Namen der Anwendung für Ihre Entwicklungskopie ändern - stellen Sie sicher, dass die Namen eindeutig sind, um dieses Problem zu vermeiden (wenn es das ist, was Ihr Problem ist).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X