XMLHttpRequest works but no response/status back on callback - javascript

I have an XMLHttpRequest where i am sending an image across to be saved on my Amazon s3 bucket. It works correctly and the file goes to my bucket but i am getting no response back saying it is in process or has successfully uploaded. My code is below:
Javascript code in html page:
var ajax = new XMLHttpRequest();
ajax.open("POST",'http://www.xxxx.php',false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(theImage);
ajax.onreadystatechange=function(){
if (ajax.readyState==4 && ajax.status==200) {
console.log('success');
}
else {
console.log('ongoing...');
}
}
PHP code in xxxx.php:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])){
$imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData = substr($imageData, strpos($imageData, ",")+1);
$imgFileString = base64_decode($filteredData);
$s3Filename = time().'.png';
if($s3->putObjectString($imgFileString, $bucket , $s3Filename, S3::ACL_PUBLIC_READ) ){
echo "SUCCESS";
}
else{
echo "ERROR";
}
}
else {
echo "EMPTY";
}
?>
How can i get a callback to say when the upload has successfully been uploaded or if an error has occurred?

ajax.open("POST",'http://www.xxxx.php',false);
^^^^^^
You are making a synchronous request, so the request is being made and the response received before you assign your event handler. Don't do that. Remove false (or change it to true).

Related

How to get PHP array as responseText in ajax to pass it to certain div from ajax later

I have a general info form. When I click on submit, all values are got using javascript and send it to PHP function using ajax.
The PHP function validates the form and returns
EITHER form errors as an array
OR successful message.
I want to get the array generated by PHP on ajax side and pass it to the form to display the errors on respective form fields.
I have successfully generated the array of errors in PHP.
print_r($arrayname) shows all the values as an array.
But I don't want to show instead I want to pass it to ajax and retrieve the array in a div and do work on that array.
--------- AJAX ------
function general()
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST','addGeneral',true);
var data = new FormData();
data.append('title',document.getElementById('title').value);
data.append('firstname',document.getElementById('firstname').value);
data.append('middlename',document.getElementById('middlename').value);
data.append('surname',document.getElementById('surname').value);
xmlHttp.send(data);
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState==4)
{
var status = xmlHttp.responseText;
document.getElementById('responseG').style.display="block";
if(status=='true')
{
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else
{
document.getElementById('responseG').className="alert alert-danger";
document.getElementById('responseG').innerHTML=status;
}
}
}
}
---- PHP FUNCTION ---
public function addGeneral()
{
$status=array();
extract($_POST);
$this->form_validation->set_rules('title','Title','required',array('required' => 'You must provide a %s.'));
$this->form_validation->set_rules('firstname','First Name','required');
$this->form_validation->set_rules('middlename','Middle Name','required');
$this->form_validation->set_rules('surname','Surname','required');
if($this->form_validation->run()===FALSE)
{
$status=$this->form_validation->error_array();
}else
{
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
$this->Manage_employee_model->update_employee($data);
$status=array('true');
}
}
Once a PHP script finished running and the browser receives the end of the HTML response, it's over, you can't directly modify the output already sent with more PHP. What you can do it use AJAX to get the data and render it on the client side using JS, or render it on the server side and just inject the result with JS.
Client rendering
For this you just need your PHP script to return the data, then loop over it and append each item to your div in JS. It's a bit awkward to render things with native JS but this approach keeps the presentation in one place instead of having HTML code on your backend.
Server side
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
echo json_encode($data);
Client side
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4) {
var data = JSON.parse(xmlHttp.responseText);
document.getElementById('responseG').style.display="block";
if(data.status=='true') {
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else {
document.getElementById('responseG').className="alert alert-danger";
for(var i = 0; i < data.length; i++){
document.getElementById('responseG').innerHTML+= '<p>'+data[i]+'</p>;
}
}
}
}
Server rendering
Here we use PHP to generate the HTML string on the backend, send it back via AJAX and just append it to the div on the client side. The disadvantage here is mixing HTML templates with your backend code.
Server side
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
$html = '';
foreach ($data as $key => $item) {
$html += '<p>'.$item.'</p>';
}
echo json_encode(array('html' => $html));
Client side
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4) {
var data = JSON.parse(xmlHttp.responseText);
document.getElementById('responseG').style.display="block";
if(data.status=='true') {
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else {
document.getElementById('responseG').className="alert alert-danger";
document.getElementById('responseG').innerHTML = data.html;
}
}
}
In your php code after you have done all the checks and populated your response array just do a simple echo to return that data to ajax.
Example in php: echo json_encode($status);
The best place to put this code is under your if statement
Print error message on form
<?php
if(!empty(validation_errors())) {echo
validation_errors();}
?>

PHP write file works, but says false

I don't have much experience with PHP, but what I'm trying to do is to write content to a file. For some reason the content is written to the file, but still returns 'failed to write to file!' with the 400 status code. But the contents are successfully written to the file. How?
php code (update.php):
<?php
//get root and page of request
$content_root = $_SERVER['DOCUMENT_ROOT'] . '/Animagie/content';
$page = $_POST['page'];
//open the correct contentfile
$content_file = fopen($content_root . '/' . $page, 'w');
if (isset($_POST[$page . '-content'])) {
if (fwrite($content_file, $_POST[$page . '-content']) === FALSE ) {
echo 'failed to write to file!';
fclose($content_file);
http_response_code(400);
} else {
fclose($content_file);
http_response_code(200);
}
} else {
echo 'something went wrong!';
fclose($content_file);
http_response_code(400);
}
?>
I call update.php with following code:
editor.addEventListener('saved', function(e) {
var name, payload, regions, xhr;
//check if something changed
regions = e.detail().regions;
if (Object.keys(regions).length === 0) {
return;
}
//set editor busy while saving
this.busy(true);
// Collect the contents of each region into a FormData instance
payload = new FormData();
payload.append('page', getCurrentPage());
for (name in regions) {
if (regions.hasOwnProperty(name)) {
payload.append(name, regions[name]);
}
}
// Send the updated content to the server to be saved
function onStateChange(e) {
//check if request is finished
if (e.target.readyState === 4) {
editor.busy(false);
if (e.target.status === '200') {
new ContentTools.FlashUI('ok');
} else {
new ContentTools.FlashUI('no');
}
}
}
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '../api/update.php');
xhr.send(payload);
});
As you probably can tell it's quiet important to get the correct statuscode since I check for it and return if it's succesfull or not to the user. Anyone able to help me?
Thanks in advance!
Apperently the problem lays in the javascript check:
if (e.target.status === '200') {
new ContentTools.FlashUI('ok');
} else {
new ContentTools.FlashUI('no');
}
should be
if (e.target.status == 200) {
new ContentTools.FlashUI('ok');
} else {
new ContentTools.FlashUI('no');
}
Also after I switched the if-statement (like told by #Jon Stirling), postman wasn't refreshed yet. So it was partially a wrong if-statement on the server side & wrong if-statement on the client side.

Returning value to Javascript from PHP called from XMLHttpRequest

I am attempting to add an "Upload Image" feature to my AjaxChat window. The upload to the server works great, but now I need to be able to return the tmp_name/location of the file that was uploaded. In my Javascript I have the following (main) code (some setup code has been omitted because it is unnecessary -- The upload works as expected):
// Set up request
var xhr = new XMLHttpRequest();
// Open connection
xhr.open('POST', 'sites/all/modules/ajaxchat/upload.php', true);
// Set up handler for when request finishes
xhr.onload = function () {
if (xhr.status === 200) {
//File(s) uploaded
uploadButton.innerHTML = 'Upload';
} else {
alert('An error occurred!');
}
};
// Send data
xhr.send(formData);
My PHP code ("upload.php") is as follows:
<?php
$valid_file = true;
echo '<script type="text/javascript">alert("PHP Code Reached");</script>';
if($_FILES['photo']['name']) {
//if no errors...
if(!$_FILES['photo']['error']) {
//now is the time to modify the future file name and validate the file
$new_file_name = strtolower($_FILES['photo']['tmp_name']); //rename file
if($_FILES['photo']['size'] > (1024000)) { //can't be larger than 1 MB
$valid_file = false;
$message = 'Oops! Your file\'s size is to large.';
exit("$message");
}
//if the file has passed the test
if($valid_file) {
//move it to where we want it to be
move_uploaded_file($_FILES['photo']['tmp_name'], '/var/www/html/images'.$new_file_name);
$message = 'Congratulations! Your file was accepted.';
exit("$message");
}
}
//if there is an error...
else {
//set that to be the returned message
$message = 'Ooops! Your upload triggered the following error: '.$_FILES['photo']['error'];
exit("$message");
}
}
?>
I can tell my PHP code is being run because the image uploads to the server. However, I read that I could generate a Javascript "alert" popup from within the PHP using the following code:
echo '<script type="text/javascript">alert("PHP Code Reached");</script>';
But the above line does not seem to be doing anything. Is this expected since I'm using an XMLHttpRequest, rather than running the PHP directly?
Ultimately my goal is to pass the name of the uploaded file back to the Javascript that called the PHP so that I can create the image url, put it in img tags, and send it to the chat window using ajaxChat.insertText() and ajaxChat.sendMessage(). I'm not sure if this is possible the way I'm running my PHP, though. How would one go about doing this?
When you use XMLHttpRequest, the output of the server script is in the responseText of the object. So you can do:
xhr.onload = function () {
if (xhr.status === 200) {
//File(s) uploaded
uploadButton.innerHTML = xhr.responseText;
} else {
alert('An error occurred!');
}
};
If you want to send back multiple pieces of information, such as an informative message and the name of the file, you can use JSON to encode an associative array, which will become a Javascript object when you parse it.

Php file upload using xmlhttprequest

I am really confused in using xmlhttprequest. I want to send a file to server. Is it necessary to use formdata to send the file. I am trying to send directly using xmlhttprequest. Instead of getting a file, I am getting only a text at server side.
var Stu_Image = localStorage.getItem('StuImage');
alert(Stu_Image);
nImageRequest[i] = new XMLHttpRequest();
nImageRequest[i].open("POST", "http://10.xxx.xx.xx/server/api/upload_image.php", true);
// var ImageFile = new Image();
ImageFile = "image="+Stu_Image;
nImageRequest[i].setRequestHeader("Content-type", "application/x-www-form-urlencoded");
alert(ImageFile);
nImageRequest[i].onreadystatechange = function (oEvent)
{
if (nImageRequest[i].readyState == 4)
{
alert("4 status:"+ nImageRequest[i].status+"-------"+ nImageRequest[i].statusText);
if (nImageRequest[i].status == 200)
{
alert(nImageRequest[i].responseText);
return;
}
else
{
alert("Error:"+ nImageRequest[i].statusText);
}
}
else
{
alert("Error:"+ nImageRequest[i].readyState +"----"+nImageRequest[i].statusText);
}
};
nImageRequest[i].send(ImageFile);
This is my php file
header("Access-Control-Allow-Origin: *");
$data = $_POST['image'];
//$data = $_FILES['image']['name'];
echo "".$data;
$fileData = base64_decode($data);
echo ".....".$fileData;
$uploads_dir = "server/api/uploads/";
move_uploaded_file($fileData, $uploads_dir);
if(!file_exists($fileData) || !is_uploaded_file($fileData))
{
//echo "";
echo "No upload";
}
else
{
echo "uploaded";
}
This is how I got Stu_Image
function loadImage(Value)
{
var reader = new FileReader();
reader.readAsDataURL(document.getElementById("LoadImage").files[0]);
ImgFile = document.getElementById("LoadImage").files[0];
/
// alert(ImgFile);
localStorage.setItem('StuImage',ImgFile);
alert(ImgFile);
// alert(url);
reader.onload = function (Event)
{
document.getElementById("PreviewImage").src = Event.target.result;
};
};
Okay, so after wasting a few days, I got the answer to this question. I hope the answer helps someone if he/she gets stuck here.I am not posting the code as it is very big. I was not encoding the image before sending to server.
So the right method is
1 Store Image on Canvas.
2 Encode it using canvas.toDataURL method and send using xmlhttprequest.
3 Decode it as server side. I used php function base64_decode to do it.
4 Use imagecreatefromstring() method to convert decoded string to image and then use imagejpeg() or imagepng() method to get the image.
Hope it helps someone. Happy to post code if required by anyone.

Return value from php to javascript

I writing a registration/login form, I am sending user info via POST to a PHP that is looking in a DB. I would like that the PHP returns an ok or wrong value to the js and I don't now how to do it.
Here my js:
ui.onClick_regsubmit=function()
{
var fname=document.getElementById('fname').value;
var lname=document.getElementById('lname').value;
var password=document.getElementById('password').value;
var mail=document.getElementById('mail').value;
var affiliation=document.getElementById('affiliation').value;
var data = new FormData();
var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new activeXObject("Microsoft.XMLHTTP");
data.append("fname",fname);
data.append("lname",lname);
data.append("password",password);
data.append("mail",mail);
data.append("affiliation",affiliation);
xhr.open( 'post', 'PHP/registration.php', false );
xhr.send(data);
window.alert(affiliation);
}
And the php:
<?php
mysql_connect('localhost','root','') or die('Cannot connect mysql server');
mysql_select_db('ChemAlive_login') or die('cannot connect database');
$lname=$_POST['lname'];
$fname=$_POST['fname'];
$password=$_POST['password'];
$mail=$_POST['mail'];
$affiliation=$_POST['affiliation'];
$q=mysql_query("select * from login where mail='".$mail."' ") or die(mysql_error());
$n=mysql_fetch_row($q);
if($n>0)
{
$q=mysql_query("select password from login where mail='".$mail."' ");
$pp=mysql_fetch_row($q);
if($pp[0]=$password) echo "ok";
else echo "wrong";
}
else
{ $insert=mysql_query("insert into login values('".$fname."','".$lname."','".$mail."','".$password."','".$affiliation."')") or die(mysql_error());}
?>
I would like to return to js this ok or wrong value. How to do it?
xhr.onload=function()
{
if (xhr.status==200)
{
alert(xhr.response);
}else
{
alert("unknown server error");
}
}
it will be better if the server sends a response code, and javascript will transfer this code to the text. For example:
onload=function()
{
switch(xhr.response)
{
case "0":{alert("unknown error")};break;
case "1":{alert("email is already used")};break;
...
}
}
I think thought it is clear
I do not have the rep to comment or I'd ask for details, but if you can consider using ajax, it could look something like this:
php:
$doit = //your query;
if($doit){
$youdid = 'ok';
}
else{
exit('1');
}
js:
$(document).ready(function () {
var foo = $("#formfield")val();
$.ajax({
"foo":foo;
type: 'POST',
url: 'some.php',
success: function(responseText) {
if(responseText == "1") {
alert("Leave instantly");
};
}
else {
alert("One of us");
}
If you want to return either ok or wrong to the JavaScript to handle you could do something like this in your registration.php page:
$q=mysql_query("select password from login where mail='".$mail."' ");
$pp=mysql_fetch_row($q);
if($pp[0]=$password){
header('Content-Type: application/json');
echo json_encode(array('password' => 'ok'));
}else{
header('Content-Type: application/json');
echo json_encode(array('password' => 'wrong'));
}
I have not fully testing this, but the idea is to set the header to return json and then send it a JSON string.
Does that make sense?
Like I said in my comment below I have only used jQuery for AJAX. But here is a little something of what I know about XMLHttpRequest and my undertsanding of how you would test what you get back.
You can set up a listener for when you get a response back onreadystatechange and then put the response in a variable var pass = xhr.response and then just output the text to an alert box like alert(pass.password).
if (xhr.onreadystatechange === 4 && xhr.status === 200){
var pass = xhr.response;
//should output either ok or wrong
alert(pass.password);
}
Read more about XMLHttpRequest here
Let me know if that works.

Categories