Hello guys I successfully found a method that claims to make a file input file into a base 64 string in JavaScript so I successfully sent that base 64
string by JSON v
Brad indicated a more efficient way, but following your code I see that you keep the string not the result of base64_decode.
Change
//Photo upload section
$photo=$upload_info_json_object->photo;
base64_decode($photo);
for
//Photo upload section
$photo=$upload_info_json_object->photo;
$photo=base64_decode($photo);
I see a couple of major issues:
On line 13 of x.php, you call base64_decode
, but don't assign the result. If should read as $photo = base64_decode($photo);
The prefix used to display the image in a browser (data:image/jpeg;base64,
) should not be included in the file written. Thus your final decode should look something like:
$photo = base64_decode(explode(",",$photo,2)[1]);
Where explode is splitting on the first comma, returning an array, and we're accessing just the second item which contains the rest of the string since we're limiting it to 2 items, meaning it's safe if there's a comma later on. (Using substr
and strpos
may be a little more efficient, so that's a fine option as well)
If the file type isn't always JPEG, you'll want to parse that first part as well so you know what to use in the filename (at least if you care about portability).
If that doesn't resolve your issue, start troubleshooting incrementally: take the value from JavaScript and compare it to the value from PHP before decoding. Are they identical? Often you can get some additional encoding (e.g. URL-encoded) depending on configuration, so it's important to rule that out.
If the strings look identical, I'd move on to the base64_decode
function and set the optional $strict
parameter to true
. This will cause it to return false if there are any non-base64 characters (instead of silently dropping them).
You could also try testing with a small known string (bypassing the encoding to ensure that isn't the issue), such as a 1x1 pixel black GIF:
R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=
You could test the same directly in PHP to eliminate any of the encoding or decoding of the JSON object or its processing in transit from being the issue.
I think you should abandon your current methodology entirely and replace it with this:
<form action="x.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="first_name" value="John" />
<input type="hidden" name="last_name" value="Smith" />
<input type="file" name="photo" accept="image/*" />
<input type="submit" value="Upload Photo" />
</form>
Then, on your server-side code, inspect the results like so:
<?php
print_r($_POST); // All of your post fields
print_r($_FILES); // All of the file uploads
Look into move_uploaded_file() when you know where you want to put it.
There are many benefits:
accept="image/*"
)Hey every one I found out for some reason the way the base 64 string is structured in the JSON seems to not be compatible in the PHP side. I did a test where I sent a base 64 encoded string in a JSON object to the PHP side and I compare it to a encoded base 64 string of the same file from
https://www.browserling.com/tools/image-to-base64 in a if else statement for example if for it match and else where it says it don't match and to my surprise I found out it gave me the else statement meaning they don't match message so I found out that the way the base 64 string is
encoded and structured in the JavaScript side is not being read right in the PHP side. That's why, any photo viewer apps could not read the photo. I assume its certain characters in the JSON encoded base 64 string but both of the compared strings from my if
else statement test look exactly the same so I solved this problem by googling for a method that can escape special characters in the client side and I found this method call encodeURIComponent(); it escapes special characters but for URLs so I said well i'm
ma try it to my surprise when I used that on the encoded base 64 string for the JSON object it successfully made that base 64 string understandable in the PHP server side and I was able to view the photo with no problems
Here is my working example
index.php
<style>
#photo-input{
display: block;
margin-bottom: 50px;
}
</style>
<script>
document.addEventListener('DOMContentLoaded',function(){
document.querySelector('#submit').addEventListener('click',function(){
var photo_input= document.querySelector('#photo-input').files[0];
//Convert #photo-input content into a base 64 string
var reader = new FileReader();
reader.readAsDataURL(photo_input);
reader.onload = function (){
var photo_input_result= reader.result;
sendUploadInfo(photo_input_result);
}
//
});
function sendUploadInfo(photo_input_result){
//Remove the data:image/file_extension;base64, prefix by not removing this you wont be able to view this as a file in any computing application
var remove_the_photo_file_reader_prefix= photo_input_result.split(',')[1];
//
//Escape incompatible characters that won't work properly in JSON and PHP
var escape_incompatible_characters_from_the_photo= encodeURIComponent(remove_the_photo_file_reader_prefix);
//
var photo= escape_incompatible_characters_from_the_photo;
//<JSON data>
var upload_info = {
first_name: "John",
last_name: "Smith",
photo: photo
};
//</JSON data>
var upload_info_json_object= 'upload_info_json_object='+JSON.stringify(upload_info);
//<AJAX>
var xhr= new XMLHttpRequest();
xhr.onreadystatechange= function(){
if(xhr.readyState == 4){
document.querySelector('#output').innerHTML= xhr.responseText;
}
}
xhr.open('POST','x');
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(upload_info_json_object);
//</AJAX>
}
});
</script>
<input type='file' id='photo-input'>
<button id='submit'>Send JSON data</button>
<div id='output'></div>
x.php
<?php
$upload_info_json_object = json_decode($_POST['upload_info_json_object']);
$first_name= $upload_info_json_object->first_name;
$last_name= $upload_info_json_object->last_name;
//Photo upload section
$photo= $upload_info_json_object->photo;
//Decode into a file
$photo= base64_decode($photo);
file_put_contents('geeksforgeeks-22.jpg',$photo);
//
?>
<h1><?php echo $first_name.' '.$last_name.' just uploaded a photo.'; ?></h1>
so my problem now is if I try to use the encodeURIComponent(); method on a video encoded in a base 64 string it gave me this error
Uncaught RangeError: Invalid string length
So I need to find another method that escape the characters in the encoded base 64 string in the JSON object on the client side to have it to be understandable in the PHP side in other words something like what encodeURIComponent(); does but not for URLs but for a base 64 encoded string on the client regardless how big the encoded base 64 string is on the client side.