PHPs base 64_decode is not converting base64 string to a real workable image file

后端 未结 4 1545
有刺的猬
有刺的猬 2021-01-28 04:26

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

相关标签:
4条回答
  • 2021-01-28 04:47

    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);
    
    0 讨论(0)
  • 2021-01-28 04:52

    I see a couple of major issues:

    1. On line 13 of x.php, you call base64_decode, but don't assign the result. If should read as $photo = base64_decode($photo);

    2. 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.

    0 讨论(0)
  • 2021-01-28 04:58

    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:

    • A real, binary file upload without the waste and overhead of 33% base-64, nor the CPU on each side to deal with it
    • An image input that accepts just images (accept="image/*")
    • Form can be submitted by screen readers and other browser controls, rather than just some button without context
    • No need for JavaScript at all!
    • Standard streaming uploads, for less memory usage on your server.
    • No need for the encoding/decoding of a potentially huge JSON blob.
    0 讨论(0)
  • 2021-01-28 05:00

    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.

    0 讨论(0)
提交回复
热议问题