Why is $_FILES[] always empty? - javascript

The problem
I'm trying to make an AJAX file uploader with Php and Javascript. The problem I'm having is that in my upload.php script where I'm trying to use the move_uploaded_file function, the $_FILES array is always empty.
Here's what I've tried thus far
Checked file_uploads = On in /etc/php/7.2/apache2/php.ini
Checked the current working directory of uploader.php and upload.php
Checked the file permissions of uploads
Changed the uploads_tmp_dir in /etc/php/7.2/apache2/php.ini
The MWE
Html in uploader.php:
<form class="form" id="upload_form">
<input type="file" name="file_to_upload" id="file_to_upload"><br>
<input class="button" type="submit" value="Upload">
</form>
Javascript in uploader.php:
<script>
var upload_form = document.getElementById('upload_form');
var file_to_upload = document.getElementById('file_to_upload');
upload_form.addEventListener("submit", upload_file);
function upload_file (e) {
e.preventDefault();
var xhr = new XMLHttpRequest()
xhr.open("POST", "upload.php");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(new FormData(upload_form));
}
</script>
upload.php:
<?php
//$target_path = "uploads/".basename($_FILES["file_to_upload"]["name"]);
$uploaded_file = $_FILES['file_to_upload']['tmp_name'];
var_dump($_FILES); // This is always array(0) { }
if(file_exists($uploadedFile)) {
echo "file uploaded to temp dir";
} else {
echo "file upload failed"; // This is always the outcome
}
//move_uploaded_file($_FILES["file_to_upload"]["tmp_name"], $target_path);
?>

According to the PHP docs, you must specify enctype="multipart/form-data". You must also specify method="post" -- see this answer for an explanation.
So your <form> should read:
<form class="form" id="upload_form" enctype="multipart/form-data" method="post">

In one of my projects using Framework-7. I was doing the same to get file upload form submission using ajax.
Do what #kmoser suggest in his answer but do as below as well.:)
<form class="form" id="upload_form" enctype="multipart/form-data" method="post">
<input class="button" type="submit" id="submission" value="Upload">
Now, my code:
$$('#submission').on('click', function(){
//alert('here');
//var test = $('#upload_form').serializeArray();
var fileInputElement = document.getElementById('file_to_upload');
var formData = new FormData();
formData.append('myfile', fileInputElement.files[0]);
var request = new XMLHttpRequest();
request.open("POST", "https://yourwebsite/upload.php");
request.send(formData);
//console.log(request.response);
request.onreadystatechange = function() {//Call a function when the state changes.
if(request.readyState == 4 && request.status == 200) {
alert("File has been uploaded successfully!");
//console.log('here');
location.reload();
}
}
});
and at last on upload.php file write below code:
if(isset($_FILES['myfile'])) {
//echo "uploaded something";
if($_FILES['myfile']['tmp_name'] != '') {
$tmp_filenm = $_FILES['myfile']['tmp_name'];
$file_name = time()."_".$_FILES['myfile']['name'];
$file_fullpath = $today_dir."/".$file_name;
//echo $file_fullpath;
move_uploaded_file("".$tmp_filenm,"$file_fullpath");
}
}

Related

How to make my HTTP request behave the same as a form

I'd need some help with my HTTP request. Here's the setup:
A webpage load an image to a form and send it to a python server running bottle (with the form or a custom http request)
Bottle receive the file, give it as an input for a python script, receive the result and return it to the webpage
On bottle's website there's an example with a form: https://bottlepy.org/docs/dev/tutorial.html#file-uploads I've tried it and it works. Here's the code I used:
<html>
<head>
</head>
<body>
<form action="http://localhost:8080/solve" method="POST" enctype="multipart/form-data" norm="form" id='myForm'>
Select a file: <input type="file" name="upload"/>
<input type="submit" value="Start upload" />
</form>
</body>
</html>
In bottle I have:
#route('/solve', method='POST')
def solve():
file = request.files.get('upload')
name, ext = os.path.splitext(file.filename)
if ext not in ('.png','.jpg','.jpeg'):
return 'File extension not allowed.'
print(file.name)
resolved = sudoku.solve(file.file)
return str(resolved)
This "works", but the form redirects me to localhost:8080 and it's not what I want. I tried putting the target to a hidden iFrame, which prevent the redirection, but I don't manage to access the result in the body of the iFrame...
What I want: Make an HTTP request similar to the one made by the form. So I tried:
<html>
<head> </head>
<body>
<form enctype="multipart/form-data" norm="form" id="myForm">
Select a file:
<input id="fileInput" type="file" name="upload" accept="image/png, image/jpeg, image/jpg" />
<input type="submit" value="Start upload" />
<label class="button-upload" onclick="send()">Upload</label>
</form>
</body>
<script>
var _file = null;
function send() {
var file = document.getElementById("fileInput").files[0]
console.log(file)
var url = "http://localhost:8080/solve";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader(
"Content-Type",
"multipart/form-data; boundary=---------------------------169461201884497922237853436"
);
var formData = new FormData();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
formData.append("upload", file);
xhr.send(formData);
}
</script>
</html>
I've checked with the developper tool in network and the request seems to be the same as the one sent by the form, though bottle can't find the file.
The file = request.files.get('upload') returns None and file = request.files returns <bottle.FormsDict object at 0x7ff437abf400> so there's something but I don't understand how to access it!
Any help would be greatly appreciated!
Your JavaScript code seems fine, except for where you set request headers with xhr.setRequestHeader. FormData handles multipart encoding for you, you don't need to set request headers manually. I just tried it, and it seems to be working fine with bottlepy.
Overall, change your send() function as follows:
function send() {
var file = document.getElementById("fileInput").files[0]
console.log(file)
var url = "http://localhost:8080/solve";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var formData = new FormData();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
formData.append("upload", file);
xhr.send(formData);
}

Send PHP POST using Javascript AJAX

My data is not inserting into database, I get a blank response from the console log and network. I'm kinda lost my javascript source code is mix with other stack overflow answers as well as my PHP code.
<form id="requestForm">
<input type="text" name="fName" id="name">
<input type="text" name="fAddress" id="address">
<input type="text" name="fComment" id="comment">
<input type="submit" value="Submit" name="nameSubmit">
</form>
<script>
document.querySelector('#requestForm').addEventListener('submit', postRequest);
function postRequest(e){
e.preventDefault();
const params = {
fName: document.querySelector('#name').value,
fAddress: document.querySelector('#address').value,
fComment: document.querySelector('#comment').value,
};
var xhr = new XMLHttpRequest();
xhr.open('POST', 'addRequest.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function(){
console.log(this.responseText);
}
xhr.send(params);
}
</script>
</body>
Here's the PHP code:
require_once 'Database.php';
var_dump($_POST); // returns `array(0) {}`
if (isset($_POST['nameSubmit'])) {
var_dump($_POST); // shows no response
$r = $_POST['fName'];
$o = $_POST['fAddress'];
$p = $_POST['fComment'];
$query = "INSERT INTO user_request(name, address, comment) VALUES(?,?,?)";
$stmt = $db->prepare($query);
$insert = $stmt->execute([$r, $o, $p]);
if($insert){
echo 'Success';
}else{
echo 'Error';
}
}
I believe the post parameter nameSubmit does not exsist.
Use the var_dump() function for dump all $_POST
From my prespective, the only parameter given was
fName
fAddress
fComment
Why not check for request method instead?
This is better than checking if a variable exsisted or not.
You can do the checks for required parameter later after you're sure this is a POST request.
if($_SERVER['REQUEST_METHOD'] === 'POST'){
// Do whatever you want when POST request came in
}
UPDATE :
Here is the answer you wanted!
<form id="requestForm">
<input type="text" name="fName" id="name">
<input type="text" name="fAddress" id="address">
<input type="text" name="fComment" id="comment">
<button onclick="sendData();" type="button">Submit</button>
</form>
<div id="testdiv"></div>
<script>
function sendData(){
var data = new FormData();
data.append('fName', document.getElementById("name").value);
data.append('fAddress', document.getElementById("address").value);
data.append('fComment', document.getElementById("comment").value);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.onload = function () {
if(xhr.status !== 200){
// Server does not return HTTP 200 (OK) response.
// Whatever you wanted to do when server responded with another code than 200 (OK)
return; // return is important because the code below is NOT executed if the response is other than HTTP 200 (OK)
}
// Whatever you wanted to do when server responded with HTTP 200 (OK)
// I've added a DIV with id of testdiv to show the result there
document.getElementById("testdiv").innerHTML = this.responseText;
};
xhr.send(data);
}
</script>
</body>
The PHP code :
<?php
if($_SERVER['REQUEST_METHOD'] === 'POST'){
var_dump($_POST);
}else{
header('HTTP/1.0 403 Forbidden');
}
?>
To add another field, add another data.append function below data var.
The submit button MUST BE CLICKED. To allow the use of enter, add an event listener for it!.
What it looks like on my end : https://image.ibb.co/gfSHZK/image.png
Hope this is the answer you wanted.
Two issues:
1.) Params not sent properly/at all because lack of serialization. When you use form content-type your params object need to be in a particular format name=value&name2=value2. So to facilitate that you need to transform your ojbect using something like:
function getReadyToSend(object) {
var objList = [];
for (var prop in object) {
if (object.hasOwnProperty(prop)) {
objList.push(encodeURI(prop + '=' + object[prop]));
}
}
return objList.join("&");
}
So your sending becomes: xhr.send(getReadyToSend(params));
2) Your php is expecting the submit button to be sent. if (isset($_POST['nameSubmit'])) {
You don't have a variable being sent called nameSubmit you can fix this by either including it or check that each variable is set instead. I would suggest the latter that way you can error handle should 1 or more are not passed.
Suggestion: Update your onload to check status:
if (xhr.status === 200)
{
console.log(xhr.responseText);
}
else if(xhr.status !== 200)
{
console.log('Request failed. Returned status of ', xhr.status);
}
Example fiddle: http://jsfiddle.net/qofrhemp/1/, open network tab and inspect the call you will now see the params in form data for the call that fires when submit clicked.

$_POST not returning a value

I've been searching for an answer to this for several days now, but if I missed the answer in another post, let me know.
I'm trying to get into Ajax, so I have a very simple form in my index.php, with separate php and javascript files:
index.php
<div id="ajax-test">
<form action="ajax/ajax.php" method="POST">
<textarea name="someText" id="some-text" placeholder="Type something here"></textarea>
<button type="button" onclick="loadDoc()">Submit</button>
</form>
<div id="ajax-text"></div>
</div>
main.js:
function getXMLHttpRequestObject() {
var temp = null;
if(window.XMLHttpRequest)
temp = new XMLHttpRequest();
else if(window.ActiveXObject) // used for older versions of IE
temp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
return temp;
}// end getXMLHttpRequestObject()
function loadDoc() {
var ajax = getXMLHttpRequestObject();
ajax.onreadystatechange = function() {
if(ajax.readyState == 4 && ajax.status == 200) {
document.getElementById('ajax-text').innerHTML = ajax.responseText;
console.log(ajax.responseText);
}
};
ajax.open("POST", "ajax/ajax.php", true);
ajax.send();
}
ajax.php:
<?php
print_r('\'' . $_POST['someText'] . '\' is what you wrote');
?>
Whenever I try to print, it prints: " '' is what you wrote " - what am I missing/not doing/doing incorrectly that isn't allowing me to access the content of someText? I've changed my naming convention, swapped from single quote to double quote, tried GET instead of POST, but nothing worked.
You can try to set a header request and also put the data inside the send. Here an example as like as-
ajax.open("POST", "ajax/ajax.php", true);
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajax.send("someText="+document.getElementById('some-text').value);
This is probably beacuse of the error
Undefined index: someText in C:\xampp\htdocs\ssms\sandbox\ajax\ajax.php on line 3
You had a couple of issues with your code which i don't have time to list out now. This should work fine, plus i used the onkeyup() function to display the text live without even clicking on the submit button.
The Index File
<div id="ajax-test">
<form method="POST" onsubmit="return false;">
<textarea onkeyup="loadDoc()" name="someText" id="someText" placeholder="Type something here"></textarea>
<button type="button" onclick="loadDoc()">Submit</button>
</form>
<div id="ajax-text"></div>
</div>
<script type="text/javascript" src="main.js"></script>
The Main Javascript file
function _(x) {
return document.getElementById(x);
}
function ajaxObj ( meth, url ) {
var x = new XMLHttpRequest();
x.open( meth, url, true );
x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
return x;
}
function ajaxReturn(x){
if(x.readyState == 4 && x.status == 200) {
return true;
}
}
function loadDoc() {
var someText = _("someText").value;
var ajax = ajaxObj("POST", "ajax/ajax.php");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
_('ajax-text').innerHTML = ajax.responseText;
console.log(ajax.responseText);
}
}
ajax.send("someText="+someText);
}
The PHP AJAX File
if(isset($_POST['someText'])){
$someText = $_POST['someText'];
echo "\"$someText\"" . ' is what you wrote';
exit();
} else {
echo "An error occured";
exit();
}

Ajax post xmlhttprequest "processing"

I've got this code:
<script>
function ajax_post(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "my_parse_file.php";
var fn = document.getElementById("first_name").value;
var ln = document.getElementById("last_name").value;
var vars = "firstname="+fn+"&lastname="+ln;
hr.open("POST", url, true);
// Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var return_data = hr.responseText;
document.getElementById("status").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
hr.send(vars); // Actually execute the request
document.getElementById("status").innerHTML = "processing...";
}
</script>
<?php
echo 'Thank you '. $_POST['firstname'] . ' ' . $_POST['lastname'] . ', says the PHP file';
?>
<html>
<head>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
First Name: <input id="first_name" name="first_name" type="text"> <br><br>
Last Name: <input id="last_name" name="last_name" type="text"> <br><br>
<input name="myBtn" type="submit" value="Submit Data" onclick="ajax_post();"> <br><br>
<div id="status"></div>
</body>
</html>
However, I only get "processing" in the browser when running the code. Is there anything wrong? I am running it on XAMPP, if that might be a part of the problem. Thanks for the help!!

I can't find what's wrong with my javascript-ajax-php "upload file" code

this is my first question here (usually I like to find my own ways to solve problems) but I just can't find problem in my file upload code. It's supposed to use AJAX. I simplified everything so it would be easier for you to read. Here is HTML form:
<form id="fileForm" enctype="multipart/form-data" method="POST" action="php/uploadfile.php">
<p>Insert file: <input type="file" id="fileUp" name="fileUp" />
<button type="submit" id="uploadButton" onclick="sendFile();">Upload</button></p>
</form>
Now here goes javascript sendFile() function:
function sendFile()
{
var forma = document.getElementById("fileForm");
var failas = document.getElementById("fileUp");
var uploadButton = document.getElementById("uploadButton");
forma.onsubmit = function(event)
{
event.preventDefault();
}
uploadButton.innerHTML = "Uploading, please wait!";
var newFile = failas.files[0];
var formData = new FormData(forma);
formData.append("fileUp", newFile, newFile.name);
alert(newFile.name);// Here it says filename.jpg it means everything is ok at this stage
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
alert (xmlhttp.responseText);
}
}
xmlhttp.open("POST", "php/uploadfile.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(formData);
}
And php:
<?php
echo var_dump($_FILES);
?>
It should alert contents of $_FILES, but it says array(0){} even if I try $_REQUEST. So, if anyone could suggest what may be wrong, it would be appreciated :]

Categories

Resources