25. januar 2006 - 15:41Der er
23 kommentarer og 3 løsninger
Gør sådan så POST requesten ikke kommer igen uden brug af header
Vi starter med et exempel. Jeg har et forum, og hver gang man skriver en besked, og derefter refresher siden, så bliver beskeden indsat igen. Jeg ved godt hvorfor, men hvordan retter man det uden brug af en header? Jeg har prøvet at bruge et meta refresh tag, uden held!
Jeg mener den bedste løsning er at bruge 2 filer. Altså en til visning af forum + forms, og så en til at indsætte data og returnere brugeren til den foregående side.
Jo det ville være en idé, ret god faktisk, men... Nu er det sådan at jeg har et stort system på mere eller mindre 40 filer plus 11 tabeller i databasen. Den omtalte fejl opstår i 16 af filerne, så det vil sige at jeg får 16 NYE filer som bare fylder.
Som sagt foroven er det er system, og forummet var bare et exempel. Forummet består af ca. 10 filer og indeholder også et svar/afvis/accepter system ligesom eksperten har.
Jeg har læst at man kan tjekke om POST værdien indeholder det samme som den sidst skrevne besked, men hvordan kan jeg gøre det uden at skulle tilføje noget til tabellen i databasen?
Der er vel egentlig et par måder at gøre det på. Enten med en session eller ved at tjekke det sidst indsatte af denne bruger.
DB-tjek: if(isset($_POST['navn'])) { if(mysql_result(mysql_query("SELECT felt FROM tabel WHERE bruger = ".$_SESSION['brugernavn']."' ORDER BY id DESC LIMIT 1"), 0) != $_POST['variabelnavn']) { mysql_query("INSERT INTO ...... "); } }
jeg har ændret lidt i koden, (har indsat det i et ønskeliste system)
<? include "mysql.php";
if ($_POST[submit]) {
if ($_SESSION['brugernavn'] == "") { echo "Du skal være logget ind for at kunne skrive ansøgninger."; exit; } if ($_POST[oenske] == "") { echo "Du mangler at skrive dit ønske"; exit; }
if(mysql_result(mysql_query("SELECT oenske FROM oensker WHERE brugernavn = ".$_SESSION['brugernavn']."' ORDER BY id DESC LIMIT 1"), 0) == $_POST['oenske']) { echo " "; exit; } else{ $brugernavn = $_SESSION['brugernavn']; mysql_query("INSERT INTO oensker (oenske, brugernavn) VALUES ('$_POST[oenske]','$brugernavn')") or die(mysql_error()); echo "Dit ønske er afsendt!"; } }
men det virker ikke. Ønsket bliver indsat endnu en gang hvis man opdatere/refresher siden. plus at jeg for denne fejl:
Warning: mysql_result(): supplied argument is not a valid MySQL result resource in oenske.php on line 34
Jeg svare nok ikke mere nu, først når jeg kommer hjem iaften. Dette tog lidt længere tid end jeg havde regnet med, sorry :-)
Håber dog du finder frem til en løsning på ovenståene
Og der er et felt der hedder "id" i databasen? Men ellers så smid hele mysql_result(.......) udenfor og smid or die(mysql_error()) på, og se hvor fejlen opstår.
Du behøver ikke skrive én eneste fil mere for at bruge en HTTP-location header. Du kan bare poste mod dokumentet selv ... og derefter redirecte til dokumentet selv med en header. Så kan du stadigvæk ikke lave dobbelt posts :)
Måden jeg personligt har løst dette problem på er faktisk meget enkelt..
Lige efter jeg har smidt ind i databasen eller hvad det nu er jeg vil med nogen post data, kører jeg en header("bla bla bla") som loader samme side som før. altså henter adressen i adressebaren, og bliver sendt til siden med det samme igen. Så brugeren opdager ingen ting. Og systemet er sikret for at blive postet mange gange ved fx F5
jo men problemet med en header er at den kun kan bruges FØR der kommer output. Det er jo lidt skidt når de fleste af mine filer indeholder over 300 linier (og det er kun php, ikke designet)
Jeg vil lige lege lidt med dit jaw!
olebole-> Jeg forstår desværre ikke hvad du mener, men din løsning er på en eller anden måde den bedste i mine ører, vil du være så venlig at uddybe?
Forskellen mellem min og de andres er, så vidt jeg forstår, ret lille. Jeg gør det i 2 filer, og de andre i én og samme fil. Du skal jo bare sørge for at smide dit insert-script og headeren øverst i filen, og så redirecte til samme side.
Ok, har lige prøvet med en header, det virker desværre ikke, plus at jeg for en header fejl. Den der siger at der har været output.. her er mit dokument:
<?php session_start();
if(!empty($_SESSION['brugernavn'])) { ?>
<?php include "mysql.php";
if ($_POST[tilfoej]) {
$forfatter = $_SESSION['brugernavn'];
mysql_query("INSERT INTO links (link,beskrivelse,forfatter) VALUES ('$_POST[link]', '$_POST[beskrivelse]', '$forfatter')") or die(mysql_error());
har lige tænkt lidt, og det er unfair hvis jeg bare giver alle pointene til pallotto. Ved godt 30 point ikke er meget, men det er jo princippet der tæller. De andre svar i kom med virker sikkert også, det bare bare mig som ikke kunne få det til at virke.
Så derfor - læg et svar alle sammen, som mener de har hjulpet
Output-buffering (op_start() og op_flush()) er panikløsninger, der oftest bliver brugt til at redde skidt kode. Det grovæder server-hukommelse - da hele siden gemmes her - og bør defor undgåes, såvidt det overhovedet er muligt.
Det er ikke svært at undgå output-buffering i forbindelse med brug af headers ... der må blot ikke udskrives noget til dokumentet, før headeren bliver sat. Gør man ikke det, udløses ingen fejl :)
Uh, det var nogle vigtige oplysninger olebole ! :S Jeg har skam prøvet at gøre det uden brug af ob_start(); og ob_end_flush(); men som jeg postede i 14:38:49 fik jeg en fejl! :( ingen har dog prøvet at hjælpe udover jaw, men det forstår jeg ikke helt.
Dokumentets HTTP-header og head-elementet i HTML-koden er to forskellige ting :)
Når et dokument sendes over HTTP-protokollen, sendes en header i forvejen. Den fortæller browseren forskellige ting, den skal vide for at kunne behandle det efterfølgende dokument korrekt. Denne header kan man skrive til - i PHP med: header("[ET_HEADERFELT_NAVN]: [EN_VÆRDI]");
Så snart serveren begynder at sende selve dokumentets indhold, kan man ikke længere skrive til HTTP-headeren - den er afsluttet - og du får en fejl, der siger noget med at headeren allerede er sendt. Blot et enkelt tegn - eller en tom linje - regnes for en del af dokumentets indhold.
Håber, det hjalp på forståelsen af problemet/fænomenet :)
jaw >> Jeg har kodet PHP siden 99, så jeg har selv lavet _rigtig_ mange fejl! Desuden har jeg været meget aktiv på E i ligeså lang tid ... det giver vel en vis skarphed i nethinden ;o)
- og tak for points til php_programmoer =)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.