I have an issue with my AJAX formData object. If select a file in the input and I send this with AJAX the array is empty. I hope somebody can help me with this. Below my code
HTML and JavaScript
<form method="post" id="quoteform">
<input type="file" name="uploadfile" id="quote"/>
<input type="submit" value="upload"/>
</form>
<script type="text/javascript">
document.getElementById("quoteform").addEventListener("submit", function(){
var files = document.getElementById("quote").files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i]
formData.append('files[]', file);
}
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "linktophpfile.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send('upload='+formData);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
}
event.preventDefault();
});
</script>
PHP
<?php
if(isset($_POST['upload'])){
print_r($_FILES);
}
?>
The PHP file returns
Array
(
)
when you upload files then you can't use application/x-www-form-urlencoded you have to use multipart/form-data
you shouldn't mix strings with formData send('upload='+formData) it will only result in you uploading a string equal to upload=[Object object]
you should instead just send the formData and let the XHR or Fetch handle the content-type for you automatically.
If you want an array then i presume you also want the attribute mulitple? You could always add in the required and accept="image/*, .txt" for good measure
You don't manually have to add in all files to a formdata if you just use the first constructor argument that accepts a form element, everything from the form will be added
<form method="POST" action="https://httpbin.org/post" id="quoteform" encoding="multipart/form-data">
<input multiple type="file" name="files[]" id="quote" required />
<input type="submit" value="upload"/>
</form>
<script>
// html (xml) should mark the settings, behavior as it mostly always have done
// in all years way back and the js should provide enhancement and
// be more generally written to enhance the site (if js where
// to be turned off - most unlikely, I for once have it disabled in my phone)
// static sites works better without ads + annoying cookie popups
// it's a good thing Brave have quick toggle to enable scrips for js-only pages
function ajaxify (evt) {
evt.preventDefault()
var form = evt.target
var formData = new FormData(form)
fetch(form.action, {
method: form.method,
body: formData
}).then(res => res.text()).then(alert)
}
document.getElementById("quoteform").addEventListener("submit", ajaxify)
</script>
Related
I'm trying to record videos on browsers of mobile devices and send that videos to my PHP server. But when I inspect/debug my code in PHP the array $_FILES is empty. I'm sure that something is wrong in my code of JavaScript because of my lack of knowledge.
Here is my HTML / Javascript code :
<body>
<header>
<h1>HTML5 Video & Audio Input</h1>
<h2>Capturing Media with HTML and passing the data to PHP</h2>
</header>
<form method="post" action="serverTest.php" id="myform" enctype="multipart/form-data">
<label for="capture">Capture Media</label>
<input name= "uploadedVideo" type="file" id="videograbado" accept="video/*" capture="user-scalable" multiple />
<video id="player" controls></video>
</form>
<script>
document.addEventListener('DOMContentLoaded', (ev) => {
let form = document.getElementById('myform');
//get the captured media file
let input = document.getElementById('videograbado');
input.addEventListener('change', (ev) => {
console.dir(input.files[0]);
if (input.files[0].type.indexOf("video/") > -1) {
let video = document.getElementById('video');
var video1 = input.files[0];
video = window.URL.createObjectURL(input.files[0]);
var formData = new FormData();
formData.append('video-filename', input.files[0].name);
formData.append('video-blob', video);
xhr('serverTest.php', formData, function (fName) {
window.open(location.href + fName);
});
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
callback(location.href + request.responseText);
}
};
request.open('post', url, true);
request.send(formData);
}
}
})
})
</script>
</body>
Any advice or suggestion are welcome.
Sources:
https://www.youtube.com/watch?v=dbrez37HlJM
https://github.com/muaz-khan/RecordRTC/tree/master/RecordRTC-to-PHP
Your FormData object contains two things:
formData.append('video-filename', input.files[0].name);
The filename, which is a string.
formData.append('video-blob', video);
The value of video which is the return value of createObjectURL, which is also a string.
If you want $_FILES to be populated, then you need to upload a file.
formData.append('video', input.files[0]);
I would like to send the data to another php page using javascript but it does not work as expected.
Let just say I have the form:
<form id="myForm">
<label for="name">Username</label>
<input type="text" name="name" id="name">
<label for="pass">Password</label>
<input type="password" name="pass" id="pass">
<button id="submit" type="submit" >OK</button>
</form>
and the script:
const myForm = document.getElementById('submit');
myForm.addEventListener('submit', function(e){
e.preventDefault();
const data = new FormData(this);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'getData.php', true);
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send(data);
});
The php file is unable to recieve the data at the moment. How can it fix with ajax or any other equivalent code?
Make change in button
<button id="submit" type="button" onclick="sendData()" >OK</button>
Then add javascript function.
<script>
function sendData(){
var name = document.getElementById("name");
var password = document.getElementById("pass");
if (name) {
$.ajax({
type:"POST",
url:"path-to-php-file.php",
data:'name='+name+'&pass='+password,
success:function(data){
alert(data);
}
});
}
</script>
Then create php file where you will get data.
path-to-php-file.php
<?php
$name = $_POST['name'];
$password = $_POST['pass'];
echo $name .'--'.$password;
?>
I cannot tell exactly what is the problem without looking at your php code.
Maybe there is something wrong with the Content-Type header.
document.getElementById('submit').addEventListener('submit', (e) => {
e.preventDefault();
const data = new FormData(this); // Here 'this' will not work, you gotta loop through the inputs and append them to the FormData object.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
// do something
}
xhr.open('POST', 'getData.php', true);
// the default content type is application/x-www-form-urlencoded
xhr.setRequestHeader("Content-Type", "<content type here>")
xhr.send(data);
});
Extra
What I suggest is in your case you won't really need a form element here. You could make the button a normal button and make the form a div(not special benefit, just for clean code). Assign a function to the onclick event of the button and loop through the inputs and append them to the form data(if the content type is application/x-www-form-urlencoded) object and send it to the server.Use this method if you have a complex form like a interactive form like Google or Microsoft have.
And also you do not want to use preventDefault() method if you follow my method.
This is what most professionals would do.
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);
}
This is my javascript
function ajax_post(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
var url = "LiveUpdate.php";
var sb = document.getElementById("LiveUpdate").value;
var FirstName = document.getElementById("FirstName").value;
var images = document.getElementById("images").value;
var vars = "update="+sb+"&FirstName="+FirstName+"&images="+images;
hr.open("POST", url, true);
// Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "multipart/form-data");
// 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("message").innerHTML = return_data;
}
}
// Send the data to PHP now... and wait for response to update the status div
var formData = new FormData(document.querySelector("form"));
hr.send(formData); // Actually execute the request // Actually execute the request
document.getElementById("message").innerHTML = "processing...";
}
//show image before uploading
var loadFile = function(event) {
var output = document.getElementById('output');
output.src = URL.createObjectURL(event.target.files[0]);
};//end image
and this is the form. javascript and the form is in the same file. the file name is sample.php
<form action="popup.php" method="post" id="myForm" name="myForm" enctype="multipart/form-data">
<div id="message"></div>
<img src="" id="output" />
<input type="file" class="filestyle" data-buttonBefore="true" accept=".png, .jpg, .jpeg" onchange="loadFile(event)" name="images" id="images">
<input class="form-control" type="text" placeholder="First Name" name="FirstName" id="FirstName" value="">
Update
</form>
the idea in this code is. i want to insert the basic information like FirstName and Image into the database live without refreshing the page. the reason why i choose tag to submit the ajax. so the page url Account.php?Edit=1 will not change to Account.php because if it change to account.php the popup editing mode will be close. the problem in this code is. i don't know how to fix the error Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 can anyone help me how to fix this. thank you!
The browser sets the correct headers (including the correct multipart boundary indication in the Content-type) if you haven't manually specified anything.
So all you need to do is remove the following line:
hr.setRequestHeader("Content-type", "multipart/form-data");
Otherwise you will need to set the boundary yourself as it is suggested by Ellias Van Ootegem in Uploading a file with XMLHttprequest - Missing boundary in multipart/form-data:
hr.setRequestHeader("Content-type","multipart/form-data; charset=utf-8; boundary=" + Math.random().toString().substr(2));
Just remove the setRequestHeader()
This works as well. Taken from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
const config = {
headers: {
Authorization: Bearer ${localStorage.token},
"Content-Type":
"multipart/form-data; boundary=---------------------------974767299852498929531610575"
}
};
I tried to make an ajax image uploader I was wondering how to send an image via a xmlHttpRequest .
Firstly i tried to send with a FormData object
var formdata = new FormData();
formdata.append('file',fileInput.files[0]);
But when I do print_r in the requested php file to _POST and _FILES but the function returned an empty array .
I tried also doing it with only the send() method but it also doesn't work where is the problem
Note : i didn't forgot the "multipart/form-data" in the setHeader.
To use the XML HTTP request features in your application, you must learn to upload files on the background with Ajax
1) Define the input elements for the file upload. Use the upload() method for the button click event to upload the file when the button is click.
<input type="file" id="uploadfile" name="uploadfile" />
<input type="button" value="upload" onclick="upload()" />
2) In the upload() method, create a FormData interface instance, and add the file element with the attached file into it. Use the send() method to send the FormData to the server.
<script>
var client = new XMLHttpRequest();
function upload()
{
var file = document.getElementById("uploadfile");
/* Create a FormData instance */
var formData = new FormData();
/* Add the file */
formData.append("upload", file.files[0]);
client.open("post", "/upload", true);
client.setRequestHeader("Content-Type", "multipart/form-data");
client.send(formData); /* Send to server */
}
/* Check the response status */
client.onreadystatechange = function()
{
if (client.readyState == 4 && client.status == 200)
{
console.log(client.statusText);
}
}
</script>