webForumDet fria alternativet

enctype:mulitpart/form-data validerar inte. Hur fixa?

18 svar · 1 145 visningar · startad av Danne V

Danne VMedlem sedan aug. 20068 090 inlägg
#1

Har ett uppladdningsformulär. DTD är xhtml 1.0 trans (hade strict men var tvungen att byta för att några andra grejer skulle validera).

Nu får jag fel på denna raden:

<form name="frm" method="post" onsubmit="return validate(this);" enctype="multipart/form-data">

Validatorn skriver:

Line 115, Column 95: required attribute "action" not specified
…his);" enctype="multipart/form-data">

The attribute given above is required for an element that you've used, but you have omitted it. For instance, in most HTML and XHTML document types the "type" attribute is required on the "script" element and the "alt" attribute is required for the "img" element.

Typical values for type are type="text/css" for <style> and type="text/javascript" for <script>.

Jag undrar om det kan orsakas av att validatorn kanske "räknar" fel eftersom den dessutom rödmarkerat den avslutande klammern (eller vad tecknet kallas) i den öppnande form-taggen (jag fetar samma här):

…his);" enctype="multipart/form-data"[B]>[/B]

Formuläret i sin helhet ser ut så här:

<form name="frm" method="post" onsubmit="return validate(this);" enctype="multipart/form-data">
<input type="hidden" name="pgaction" />
	<?php if ($GLOBALS['msg']) { echo '<div class="err">'.$GLOBALS['msg'].'</div>'; }?>
	<table border="0" cellpadding="0" cellspacing="0" id="uppladdningsform">	
<tr class="tblSubHead">
			<td ><a href="javascript:_add_more();" title="Lägg till fler fält">Skapa först lika många uppladdningsfält som du har filer genom att klicka här.</a></td>
	</tr>
		<tr class="txt">
			<td><div id="dvFile"><input type="file" name="item_file[]" /></div></td>
		</tr>
		<tr>
			<td><input type="submit" id="sendbutton" value="LADDA UPP!" /></td>
		</tr>
	</table>
</form>

Kan någon lista ut vad jag ska göra för att validatorn ska bli glad utan att funktionen (uppladdningen) går förlorad?

voigtann1Medlem sedan juni 20019 519 inlägg
#2

Du måste ha en action när det gäller eenctype

Line 115, Column 95: required attribute "action" not specified

fixar du det så validera den bättre på den raden.

MickeA.comMedlem sedan feb. 20034 441 inlägg
#3

Till exempel såhär:

<form name="frm" action="#" method="post" onsubmit="return validate(this);" enctype="multipart/form-data">
Danne VMedlem sedan aug. 20068 090 inlägg
#4

voigtann1 skrev:

Du måste ha en action när det gäller eenctype
fixar du det så validera den bättre på den raden.

OK...men då blir det ju lite dumt. Vad ska jag peka mot? Jag har 15 rader js som hör till, men som ligger under formuläret. Åsså ligger själva funktionen (php) efter den stängande html-taggen. Också typ 15 rader.

Ska jag skapa separat dokument av endera (eller båda) av dessa och peka mot? Eller finns det en parameter typ "void" eller "null" som jag kan lägga in i "action" för att liksom eliminera attributet?

Danne VMedlem sedan aug. 20068 090 inlägg
#5

Löst. Jag la bara in

action=""

så blev validatorn nöjd.

nitro2k01Medlem sedan aug. 20039 342 inlägg
#6

Får jag fråga, om du inte har någon action, var postas filen?

Danne VMedlem sedan aug. 20068 090 inlägg
#7

nitro2k01 skrev:

Får jag fråga, om du inte har någon action, var postas filen?

Ingenstans. Det är ett formulär för att ladda upp filer.

nitro2k01Medlem sedan aug. 20039 342 inlägg
#8

Men du måste väl ha en sida någonstans där du tar emot filerna? Även om man gör det med Ajax så har man väl normalt t ex iframe som formuläret postas mot?

Danne VMedlem sedan aug. 20068 090 inlägg
#9

nitro2k01 skrev:

Men du måste väl ha en sida någonstans där du tar emot filerna? Även om man gör det med Ajax så har man väl normalt t ex iframe som formuläret postas mot?

Nej. Filerna hamnar i en mapp, bekräftelsen (success) visas i formuläret när filen är uppladdad.

nitro2k01Medlem sedan aug. 20039 342 inlägg
#10

Jag tror inte på magi, så jag tror ändå att det finns en PHP-fil på andra sidan som tar emot den uppladdade filen, och en bit Javascript som pekar action mot den PHP-filen, även om action inte är satt från början.

Edit: Det du egentligen vill göra är kanske att ha php-filens eget namn som action. Om php-filen kallas laddaupp.php kanske du vill sätta action="laddaupp.php".

Danne VMedlem sedan aug. 20068 090 inlägg
#11

nitro2k01 skrev:

Jag tror inte på magi, så jag tror ändå att det finns en PHP-fil på andra sidan som tar emot den uppladdade filen, och en bit Javascript som pekar action mot den PHP-filen, även om action inte är satt från början.

Edit: Det du egentligen vill göra är kanske att ha php-filens eget namn som action. Om php-filen kallas laddaupp.php kanske du vill sätta action="laddaupp.php".

Heh... du får tro vad du vill. Det finns ingen annan fil. Men för att stilla din nyfikenhet ska du få se all (original)kod:

<?php
if($_POST['pgaction']=="upload")
	upload();
else
	uploadForm();

//The form having dynamic file uploader
function uploadForm() {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title> :: FILEUPLOAD :: </title>
<link href="style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
<!--
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
//-->
</script>
</head>

<body bgcolor="#C8C8C8" leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
<br>
<form name="frm" method="post" onsubmit="return validate(this);" enctype="multipart/form-data">
<input type="hidden" name="pgaction">
	<?php if ($GLOBALS['msg']) { echo '<center><span class="err">'.$GLOBALS['msg'].'</span></center>'; }?>
	<table align="center" cellpadding="4" cellspacing="0" bgcolor="#EDEDED">	
		<tr class="tblSubHead">
			<td colspan="2">Upload any number of file</td>
		</tr>
		<tr class="txt">
			<td valign="top"><div id="dvFile"><input type="file" name="item_file[]"></div></td>
			<td valign="top"><a href="javascript:_add_more();" title="Add more"><img src="plus_icon.gif" border="0"></a></td>
		</tr>
		<tr>
			<td align="center" colspan="2"><input type="submit" value="Upload File"></td>
		</tr>
	</table>
</form>
<script language="javascript">
<!--
	function _add_more() {
		var txt = "<br><input type=\"file\" name=\"item_file[]\">";
		document.getElementById("dvFile").innerHTML += txt;
	}
	function validate(f){
		var chkFlg = false;
		for(var i=0; i < f.length; i++) {
			if(f.elements[i].type=="file" && f.elements[i].value != "") {
				chkFlg = true;
			}
		}
		if(!chkFlg) {
			alert('Please browse/choose at least one file');
			return false;
		}
		f.pgaction.value='upload';
		return true;
	}
//-->
</script>
</body>
</html>
<?php
}

//function to store uploaded file

function upload(){	
	if(count($_FILES["item_file"]['name'])>0) { //check if any file uploaded
		$GLOBALS['msg'] = ""; //initiate the global message
		for($j=0; $j < count($_FILES["item_file"]['name']); $j++) { //loop the uploaded file array
			$filen = $_FILES["item_file"]['name']["$j"]; //file name
			$path = 'uploads/'.$filen; //generate the destination path
			if(move_uploaded_file($_FILES["item_file"]['tmp_name']["$j"],$path)) { //upload the file
				$GLOBALS['msg'] .= "File# ".($j+1)." ($filen) uploaded successfully<br>"; //Success message
			}
		}
	}
	else {
		$GLOBALS['msg'] = "No files found to upload"; //Failed message	
	}
	uploadForm(); //display the main form
}
?>

Vassego.

nitro2k01Medlem sedan aug. 20039 342 inlägg
#12

Det som jag sa i min redigering gäller, uppladdningen tas emot av samma fil som skriver ut formuläret, med hjälp av funktionen upload(). Om du vill göra helt "rätt" så bör du skriva in namnet på PHP-filen i action.

Edit: För övrigt ser det ut som du inte har någon som helst typkontroll för filen, alltså skulle någon kunna ladda upp en php-fil och köra genom att skriva https://www.minsida.se/uploads/filen.php (Förutsatt att du inte har skyddat den katalogen på något vis.)

yohpopsMedlem sedan feb. 20011 198 inlägg
#13

Ni pratar om varandra!
Det finns ingen annan fil som tar hand om den skickade filen, efter som allt görs i en och samma fil.
//EDIT:Too slow

Danne VMedlem sedan aug. 20068 090 inlägg
#14

nitro2k01 skrev:

Det som jag sa i min redigering gäller, uppladdningen tas emot av samma fil som skriver ut formuläret, med hjälp av funktionen upload(). Om du vill göra helt "rätt" så bör du skriva in namnet på PHP-filen i action.

Edit: För övrigt ser det ut som du inte har någon som helst typkontroll för filen, alltså skulle någon kunna ladda upp en php-fil och köra genom att skriva https://www.minsida.se/uploads/filen.php (Förutsatt att du inte har skyddat den katalogen på något vis.)

Jo, man kan inte komma åt katalogen utifrån.
Men om du vet hur man kan låsa skriptet till ett gäng filtyper så tar jag gärna emot instruktioner!

ercizMedlem sedan maj 20011 826 inlägg
#15

I sånna fall brukar jag i PHP skriva form-taggen:

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">

När samma PHP-fil som skickar formuläret tar emot det.

nitro2k01Medlem sedan aug. 20039 342 inlägg
#16

Så här typ:

		for($j=0; $j < count($_FILES["item_file"]['name']); $j++) { //loop the uploaded file array
			$filen = $_FILES["item_file"]['name']["$j"]; //file name
			if (preg_match('/^.+\.(jpe?g|gif|png)$/i', $filen)){
				$path = 'uploads/'.$filen; //generate the destination path
				if(move_uploaded_file($_FILES["item_file"]['tmp_name']["$j"],$path)) { //upload the file
					$GLOBALS['msg'] .= "File# ".($j+1)." ($filen) uploaded successfully<br>"; //Success message
				}else{
					$GLOBALS['msg'] .= "File# ".($j+1)." ($filen) could not be uploaded (move_uploaded_file returned false)<br>"; //Failure
				}
			}else{
				$GLOBALS['msg'] .= "File# ".($j+1)." ($filen) could not be uploaded (Invalid file type)<br>"; //Failure
			}
		}

Kontrollen sker med ett reguljärt uttryck enligt preg_match('/\.(jpe?g|gif|png)$/i', $filen)
Kort genomgång:
/ påbörjar uttrycket
^ Detta matchar början av strängen
.+ Detta matchar 1 eller flera valfria tecken. Punkten betyder alltså valfritt tecken, och + är en kvantifierare som anger en eller flera upprepningar av det senaste tecknet.
\. Detta matchar en punkt. Eftersom punkt normalt är ett jokertecken måste man escapea punkten.
(...|...|...) I detta uttryck definierar ... olika möjliga matchningar.
(jpe?g|gif|png) Självförklarande utom jpe?g där e? betyder att e är valfritt, alltså matchas jpg och jpeg
$ matchar slutet av strängen. Detta är viktigt. Annars skulle någon kunna ladda upp fil.jpg.php och komma förbi kontrollen. Dollar-tecknet gör att inga fler tecken får följa.
/ stänger uttrycket, analogt med öppningstecknet
i betyder case insensitive, så att ändelserna kan vara skrivna med stora eller små bokstäver.

Filnamn som fil.jpg, fil.jpeg och fil.png skulle alltså matcha, men inte namn som fil.jpg.php eller .png

Jag lade även till ett felmeddelande i else-fallet för move_uploaded_file.

Danne VMedlem sedan aug. 20068 090 inlägg
#17

nitro2k01 skrev:

S
Jag lade även till ett felmeddelande i else-fallet för move_uploaded_file.

Tack, tack! :bire

zcorpanMedlem sedan dec. 20042 245 inlägg
#18

erciz skrev:

I sånna fall brukar jag i PHP skriva form-taggen:

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">

När samma PHP-fil som skickar formuläret tar emot det.

Det är precis samma sak som att skriva <form action="" method="POST"> (och faktiskt också samma som att skriva <form method="POST"> trots att det inte är giltig HTML4 (men är giltig HTML5)).

Den tomma strängen är en giltig URL och betyder att den pekar på sig själv.

TroxyMedlem sedan mars 20041 505 inlägg
#19

nitro2k01 skrev:

Om du vill göra helt "rätt" så bör du skriva in namnet på PHP-filen i action.

En alternativ lösning om man vill ligga i framkant:

Ta bort action-attributet helt.
Byt doctype till <!DOCTYPE html>
Validera med http://validator.nu/ i fortsättningen.

:)

134 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
131 ms — hämta tråd, inlägg och bilagor (db)