Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπερα

 

Οπως ειπα, τωρα που εχω χρονο ειμαι back to the basics.

Προσπαθω να κανω deserialize δεδομενα που ηρθαν σε php αρχειο απο φορμα μεσω ajax. Και δεν μπορω (?)

 

Η φορμα

<form id="fruitform" method="post" action="http://titan:8080/form">
<div class="table">
<div class="row">
<div class="cell label">Bananas:</div>
<div class="cell"><input name="bananas" value="2"/></div>
</div>
<div class="row">
<div class="cell label">Apples:</div>
<div class="cell"><input name="apples" value="5"/></div>
</div>
<div class="row">
<div class="cell label">Cherries:</div>
<div class="cell"><input name="cherries" value="20"/></div>
</div>
<div class="row">
<div class="cell label">Total:</div>
<div id="results" class="cell">0 items</div>
</div>
</div>
<button id="submit" type="submit">Submit Form</button>
</form>

και η js

document.getElementById("submit").onclick = handleButtonPress;

var httpRequest;

function handleButtonPress(e) {
	e.preventDefault();
	var form = document.getElementById("fruitform");
	var formData = "";
	var inputElements = document.getElementsByTagName("input");
	for (var i = 0; i < inputElements.length; i++) {
		formData += inputElements[i].name + "=" + inputElements[i].value + "&";		
	}
	alert  (formData.slice(0, -1));
    var hr = new XMLHttpRequest();
    hr.open("POST", "phphandling.php");
    hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    hr.onreadystatechange = function() {
	    if(hr.readyState == 4 && hr.status == 200) {
			document.getElementById("results").innerHTML = hr.responseText;
	    }
    }
    hr.send("formData="+formData.slice(0, -1));
}

απλα πραματα. Το αλερτ ειναι οπως θα πρεπε, δηλαδη

bananas=2&apples=5&cherries=20

και το php αρχειο ειναι 

<?php
$a = array();
parse_str($_POST["formData"], $a);

echo $a['apples'];
?>

μονο αυτο. Δεν λαβαινω τιποτα πισω, ουτε καποιο λαθος στον browser. 

 

Αν κανω

echo $a['bananas'];

λαβαινω κανονικα "2" ενω αν κανω

print_r($a);

μου βγαζει μονο

Array ( [bananas] => 2 )

Γιατι δουλευει μονο για το πρωτο στοιχειο του πινακα? Η μηπως χανετε ο υπολοιπος πινακας? Αυτη δεν ειναι η στανταρ "old school" μεθοδολογια?

Σορρυ, δε μπορω να καταλαβω που ειναι το λαθος...

 

Ευχαριστω

Δημοσ.

Καταρχάς το button που έχεις σαν type submit κάντο type button και αυτό. Επιπλέον βάλτου την ιδιότητα onclick πάνω του για να μην ψάχνεις στους κώδικες σου.(δηλαδή να καλεί τη συνάρτηση. Έτσι δεν χρειάζεται και η prevent default)

 

Μετά, κάνεις var form = ... και δεν το χρησιμοποιείς πουθενά.(μάλλον ήθελες να το βάλεις στην inputElements).

Στην open βάλε και την παράμετρο true στο τέλος για ασύγχρονα δεδομένα.

Στην send βγάλε το "formData=" .

 

Στο αρχείο php σου τώρα κάνε var_dump($_POST);

Τον header btw για τώρα δεν βλέπω να έχει καμία ουσία. Μετά την for loop κάνει ένα formData = formData.slice(0,-1); να τελειώνεις με αυτό

  • Like 1
Δημοσ.

ΟΚ εκανα τις αλλαγες που μου ειπες και η var dump επιστρεφει 

array(3) { ["bananas"]=> string(1) "2" ["apples"]=> string(1) "5" ["cherries"]=> string(2) "20" }

και για να παρω ξεχωριστα τιμες αντικαθιστω με 

echo $_POST['cherries']; ή echo $_POST['apples']; κτλ

αυτο ομως συνεχιζει να μη δινει τιποτα

$a = array();
parse_str($_POST["formData"], $a);

echo $a['bananas'];

Γιατι ομως?

Δημοσ.

Γιατι δουλευει μονο για το πρωτο στοιχειο του πινακα? Η μηπως χανετε ο υπολοιπος πινακας? Αυτη δεν ειναι η στανταρ "old school" μεθοδολογια?

Σορρυ, δε μπορω να καταλαβω που ειναι το λαθος...

Το λάθος είναι ότι άλλα λες στον server και άλλα κάνεις (ή νομίζεις ότι κάνεις).

 

Συγκεκριμένα λες ότι του στέλνεις περιεχόμενο application/x-www-form-urlencoded, αλλά δεν κάνεις πουθενά urlencode το περιεχόμενό σου.

 

Αυτό που στέλνεις τελικά είναι

formdata=bananas=2&apples=5&cherries=20

πράγμα στο οποίο φανερά "κάτι δεν πάει καλά" εφόσον π.χ. ο χαρακτήρας & χωρίζει πεδία μεταξύ τους, επομένως και σε αντίθεση μ' αυτό που περιμένεις το μόνο σίγουρο είναι πως με την παραπάνω είσοδο το "apples" και το "formdata" δεν έχουν καμία σχέση μεταξύ τους.

 

Αυτό που θα έπρεπε να κάνεις είναι να κάνεις window.encodeURIComponent σε οτιδήποτε περιμένεις να περάσει αυτούσιο στον server. Για παράδειγμα, αν ήθελες η τιμή του $_POST['formdata'] να είναι το string "bananas=2&apples=5&cherries=20" θα έπρεπε να έχεις

hr.send("formData="+encodeURIComponent(formData.slice(0, -1)));

Αυτό βέβαια μάλλον δεν είναι αυτό που θέλεις γιατί μετά θα πρέπει να κάνεις parse το string σε μεταβλητές στην PHP manually (αν και γίνεται εύκολα με την parse_str).

 

Αν θέλεις το $_POST['formdata'] να είναι πίνακας με την προφανή μορφή τότε θα πρέπει να κάνεις κάτι του στυλ

var body = "";
for (...) {
    var key = "formdata[" + inputElements[i].name + "]";
    body += encodeURIComponent(key) + "=" + encodeURIComponent(inputElements[i].value) + "&";
}

γιατί αυτό που πρέπει να γίνει τελικά είναι να κάνεις encodeURIComponent και τα ονόματα και τις τιμές των μεταβλητών, αλλά όχι τα = και & που καθορίζουν το format.

 

Note ότι για να σου μεταφράσει αυτόματα (ή μετά τη χρήση της parse_str) κάτι η PHP ως πίνακα, θα πρέπει να το στείλεις με τη μορφή arrayName[key]=value.

 

Αυτά όσον αφορά το γιατί δε δουλεύει σωστά αυτό που έχεις. Πρακτικά τώρα, όπως λέει και ο Σπύρος δε νομίζω πως χρειάζεται να μπλεχτείς με το formdata[key]=value και μπορείς να στέλνεις εξίσου καλά key=value και να δουλέψεις κατευθείαν πάνω στην $_POST αντί για την $_POST["formdata"].

 

 

Επιπλέον βάλτου την ιδιότητα onclick πάνω του για να μην ψάχνεις στους κώδικες σου.(δηλαδή να καλεί τη συνάρτηση. Έτσι δεν χρειάζεται και η prevent default)

Το αν θα το βάλει inline δεν έχει σχέση με το αν χρειάζεται prevent default ή όχι.

 

Στην open βάλε και την παράμετρο true στο τέλος για ασύγχρονα δεδομένα.

To true είναι το default οπότε δεν χρειάζεται.

  • Like 1
Δημοσ.

Το αν θα το βάλει inline δεν έχει σχέση με το αν χρειάζεται prevent default ή όχι.

 

Το prevent default πήγαινε για τον τύπο του κουμπιού.

Δημοσ.
Σε ενα πιο πρακτικο επιπεδο, στελνωντας απλα



hr.send(formData);
δημιουργει/στελνει πινακα 
γιατι print_r($_POST); τυπωνει Array ( [bananas] => 2 [apples] => 5 [cherries] => 20 )


ενω το 



hr.send("formData="+encodeURIComponent(formData)); - λογω του encodeURIComponent, 
δημιουργει/στελνει string


γιατι print_r($_POST['formData']); τυπωνει bananas=2&apples=5&cherries=20


 

Η parse _str που χρησιμοποιουσα στην αρχη, δουλευει μονο με string ("Parses the string into variables") οχι με  πινακα, εξ ου και η κομπλα.

Απο κει και περα ειναι θεμα "γουστου"

 

Εγω ηθελα να προσθεσω ολα τα δεδομενα της φορμας και να στειλω πισω το αθροισμα, οποτε



hr.send("formData="+encodeURIComponent(formData));
και στο αρχειο php
parse_str($_POST['formData'], $a);
echo array_sum ($a);


Ή πιο "μαζεμενα"



hr.send(formData);
και στο αρχειο php
echo array_sum ($_POST);


 

 

//ΟΚ, το λυσαμε το προβλημα μου, παμε σε πιο γενικο θεμα, παρακατω , παιζοντας ανακαλυψα οτι

 

Η τελικη διαφορα ειναι αν θες να αναφερεσαι σε καθε μεταβλητη ξεχωριστα



hr.send("formData="+encodeURIComponent(formData));
//
parse_str($_POST['formData']);
echo $cherries;


αλλα κατι τετοιο μπορει να γινει και με 



hr.send(formData);
//
echo $_POST['cherries'];


Η πλακα ειναι οτι με τη χρηση 



hr.send("formData="+encodeURIComponent(formData));
//
parse_str($_POST['formData'], $a);


πετας ολες τις μεταβλητες σε εναν πινακα, οποτε, παλι σε πινακα καταληγεις τον οποιο δουλευεις ακριβως το ιδιο με 



hr.send(formData);
//
$_POST


Οποτε σοβαρα, ποια ειναι η διαφορα, κυριε Καβουρη?

Δε θελω πινακες? 



echo $cherries; = echo $_POST['cherries'];


Θελω πινακες?



$a['apples'] = $_POST['apples']


 

αρα γιατι να χρησιμοποιησω encodeURI Component και parse _str? Για να εχω πιο πολλες γραμμες?

 

Ευχαριστω και παλι  :-) 
Δημοσ.

Η χρήση encodeURIComponent είναι "υποχρεωτική" ανεξάρτητα του τι σκοπεύεις να κάνεις. Απλά "τυχαίνει" στο συγκεκριμένο παράδειγμα τα ονόματα και οι τιμές των μεταβλητών σου να μη περιέχουν κάποιο προβληματικό χαρακτήρα οπότε είτε έτσι είτε γιουβέτσι δε βλέπεις διαφορά (εκτός βέβαια κι αν πας να το περάσεις ως string που περιέχει & και = τα οποία είναι προβληματικά οπότε μόνο με encode δουλεύει).

 

parse_str δεν υπάρχει λόγος να χρησιμοποιήσεις σ' αυτή την περίπτωση απλά ήθελα να εξηγήσω πως συνδέονται τα κομμάτια μεταξύ τους.

 

Καβούρη? :)

Δημοσ.

Καβούρη? :)

 

 

 

 

 

τοσο καψιμο, καπου θα μου εβγαινε, μη με παρεξηγεις

 

 

 

Ναι ,εχεις δικιο  το encodeURIComponent  ειναι οντως υποχρεωτικο. 

Ναι, οκ, parse_str δεν ειναι απαραιτητο σ αυτη τη φαση... Να σε πρηξω για λιγο ακομα και να ρωτησω, που θα ηταν χρησιμο, αφου κολλησα παλι και τα βλεπω ιδια?

 

Ευχαριστω κ παλι παιδια

Δημοσ.

Δεν είναι και πολύ πιθανό να το χρειάζεσαι. Εφόσον αυτά που έρχονται από $_GET και $_POST είναι ήδη parsed, θα σου χρειαστεί μόνο αν το πρόγραμμά σου διαχειρίζεται URLs σαν URLs, π.χ. παίρνω μια σελίδα και κάνω rewrite τα links που περιέχει ή καλώ κάποιο API και μου επιστρέφει ένα URL και γω από αυτό θέλω να εξάγω την τιμή του username. Τέτοια πράγματα.

  • Like 1
Δημοσ.

Ναι βασικά είναι ότι σου αρέσει. Άλλοι προτιμούν να κάνουν ακόμα και explode το string.

 

Βέβαια θυμήσου ότι εφόσον έχεις user input από την εφαρμογή σου σίγουρα δεν την εμπιστεύεσαι σε τίποτα. Εξ αρχής πιστεύεις ότι έχει βάλει ότι ποιο "διαβολικό" για να σπάσει την εφαρμογή που με κόπο και ιδρώτα έχεις χτίσει.

 

Άρα ένα associative array είναι ποιο εύκολο για να εξετάσεις τιμή τιμή την είσοδο από το χρήστη.(το sanitization κοινός)

  • Like 1
Δημοσ.

Ναι βασικά είναι ότι σου αρέσει. Άλλοι προτιμούν να κάνουν ακόμα και explode το string.

 

Βέβαια θυμήσου ότι εφόσον έχεις user input από την εφαρμογή σου σίγουρα δεν την εμπιστεύεσαι σε τίποτα. Εξ αρχής πιστεύεις ότι έχει βάλει ότι ποιο "διαβολικό" για να σπάσει την εφαρμογή που με κόπο και ιδρώτα έχεις χτίσει.

 

Άρα ένα associative array είναι ποιο εύκολο για να εξετάσεις τιμή τιμή την είσοδο από το χρήστη.(το sanitization κοινός)

Καλα, σωστο κ αυτο. Εχεις ενα δικιο.

 

Αλλα και παλι, αμα μαζεψω τις τιμες με οποιονδηποτε τροπο και τις περασω σε PDO/PREPARE statements, δεν γινονται neutrilized ουτως η αλλως?

Δημοσ.

Καλα, σωστο κ αυτο. Εχεις ενα δικιο.

 

Αλλα και παλι, αμα μαζεψω τις τιμες με οποιονδηποτε τροπο και τις περασω σε PDO/PREPARE statements, δεν γινονται neutrilized ουτως η αλλως?

 

Εσύ μιλάς τώρα για κάποιο sqli. Για σκέψου όμως και τις περιπτώσεις XSS.(από htmlspecialchars μέχρι preg_replace) Επιπλέον για σκέψου ότι πρέπει να προβλέψεις και τις csrf κ.α.

 

Γενικά πρέπει να το προσεγγίσεις το θέμα όπως σου είπα. Δηλαδή για να είναι σωστό το input πρέπει όλες οι τιμές εισόδου να είναι μέσα στα όρια που έχεις θέσει.

του testινγ

...
$value = (int)$_POST['value'];
 
if(value >= 5 || value <=0){
  exit("Error on value, out of range. Exit!");
}
...
  • Like 1
Δημοσ.

Σπύρο αυτά που λες είναι γενικά σωστά αλλά νομίζω πως το παρακάνεις λίγο.

  • Έχω τη φρικτή υποψία ότι λέγοντας "sanitization" -- μια λέξη που σχεδόν ποτέ δε χρησιμοποιείται σωστά -- μπορεί να καταλήξουμε να μιλάμε για 100% misguided πρακτικές όπως αποθήκευση htmlspecialchars στη database και τέτοια.
  • Validation ναι, όπου έχει νόημα. Escaping/quoting/όπως θέλεις πες το ναι, παντού, εκτός από τις ελάχιστες περιπτώσεις όπου επίτηδες δεν θα το κάνεις. Αλλά τι σημασία έχει αν είναι τα input σε πίνακα ή όχι; Για καθαρά πρακτικούς λόγους πάντα καταλήγεις να τα βάλεις σε πίνακα, αλλά αυτό "απλά" σε βοηθάει να γράψεις καλύτερο κώδικα, όχι να κάνεις καλύτερα τη δουλειά.
  • Τι σχέση έχει το CSRF και η preg_replace με πίνακες και κενά ασφαλείας από είσοδο προερχόμενη από το χρήστη;
Δημοσ.

Να σημειωσω απλα οτι υπαρχει και το FormData Object της HTML5 που μπορεις αντι για 

var inputElements = document.getElementsByTagName("input");
	
for (var i = 0; i < inputElements.length; i++) {
	formData += inputElements[i].name + "=" + inputElements[i].value + "&";		
}

να κανεις γρηγορα 

var form = document.getElementById("fruitform");
var formData = new FormData(form);

και να μαζεψει ολα τα δεδομενα της φορμας σε μορφη πινακα 

το print_r($_POST); απο τον σερβερ δινει Array ( [bananas] => 2 [apples] => 5 )

Επισης, notes to self ή σε οποιον αλλο αντιμετωπισει ιδια θεματα

 

Deserialize with parse_str - http://stackoverflow.com/questions/1792603/how-do-i-php-unserialize-a-jquery-serialized-form

Php var _dump - http://www.php.net/manual/en/function.var-dump.php

Php parse_str - http://www.php.net/manual/en/function.parse-str.php

Php count the items of an array - http://www.php.net/count

Jquery, serialize - http://www.w3schools.com/jquery/ajax_serialize.asp

JS, chop last char of a string - http://stackoverflow.com/questions/952924/javascript-chop-slice-trim-off-last-character-in-string

 

ajax, xhr, xhr2, json, formdata, nodejs, file upload, load events - The Definitive Guide to HTML5 - Adam Freeman - 2011 - A press - chapters Using Ajax – Part I & Using Ajax – Part II

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...