PHP的base 64_decode不会将base 64字符串转换为实际可用的图像文件

时间:2019-07-14 02:32:13

标签: javascript php base64

大家好,我成功找到了一种方法,该方法声称可以将文件输入文件转换为JavaScript中的base 64字符串,所以我成功发送了base 64

通过AJAX通过JSON进行字符串转换,并以base 64编码的字符串在JSON方法“ photo”中发送:“ data:image / jpeg; base64,/ 9j / 4AAQSkZJRgABAQEASABIAAD / 2wB等。 >

因此,当基本64字符串到达​​PHP文件时。 PHP发挥了神奇的作用,并成功将文件存储在目标文件所在的目标文件夹中,因此当我在该文件夹中查找文件时,

当我尝试打开照片文件进行查看时,照片查看器应用程序会显示诸如image.jpg之类的字样,这似乎表明我们不支持此文件格式,而在其他照片查看器应用程序中它将显示某些内容

与此类似,所以我做错了什么?

这是我的代码

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){

var photo= photo_input_result;

//<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;

base64_decode($photo); 

$path= $_SERVER['DOCUMENT_ROOT'].'/send-json-data-by-ajax/object-based/with-file/2/images/image.jpg';

file_put_contents($path, $photo);

//

?>

<h1><?php echo $first_name.' '.$last_name.' just uploaded a photo.'; ?></h1>

4 个答案:

答案 0 :(得分:2)

我认为您应该完全放弃当前的方法,并用以下方法代替:

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

然后,在服务器端代码上,如下检查结果:

<?php
  print_r($_POST); // All of your post fields
  print_r($_FILES); // All of the file uploads

在知道要放置在move_uploaded_file()的地方,看看它。

有很多好处:

  • 真正的二进制文件上传,不会浪费33%base-64的开销和开销,也无需两端的CPU来处理
  • 仅接受图像(accept="image/*")的图像输入
  • 表格可以由屏幕阅读器和其他浏览器控件提交,而不仅仅是某些没有上下文的按钮
  • 完全不需要JavaScript!
  • 标准上传,以减少服务器上的内存使用量。
  • 不需要对潜在的巨大JSON blob进行编码/解码。

答案 1 :(得分:1)

Brad指出了一种更有效的方法,但是按照您的代码,我看到您保留的字符串不是base64_decode的结果。

更改

//Photo upload section

$photo=$upload_info_json_object->photo;

base64_decode($photo);

//Photo upload section

$photo=$upload_info_json_object->photo;

$photo=base64_decode($photo);

答案 2 :(得分:1)

我看到几个主要问题:

  1. 在x.php的第13行,您调用base64_decode,但不分配结果。如果应读为$photo = base64_decode($photo);

  2. 用于在浏览器中显示图像的前缀(data:image/jpeg;base64,)不应包含在编写的文件中。因此,您的最终解码应类似于:

$photo = base64_decode(explode(",",$photo,2)[1]);

explode在第一个逗号处分割,返回一个数组,并且我们仅访问包含其余字符串的第二个项目,因为我们将其限制为2个项目,这意味着如果后面有一个逗号。 (使用substrstrpos可能会更有效率,所以这也是一个不错的选择)

如果文件类型并非总是JPEG,则还需要解析第一部分,以便知道文件名中使用的内容(至少是在考虑可移植性的情况下)。


如果这不能解决问题,请逐步进行故障排除:从JavaScript中获取值并将其与PHP中的值进行比较,然后再进行解码。他们是相同的吗?通常,您可以根据配置获得一些其他编码(例如URL编码),因此,请务必加以排除。

如果字符串看起来相同,我将继续使用base64_decode函数并将可选的$strict参数设置为true。如果存在任何非base64字符(而不是静默删除它们),这将导致它返回false。

您还可以尝试使用已知的较小字符串(绕过编码以确保不是问题)进行测试,例如1x1像素黑色GIF:

R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=

您可以直接在PHP中对其进行测试,以消除JSON对象的任何编码或解码或其在传输过程中的问题。

答案 3 :(得分:-2)

嘿,由于某种原因,我发现每一个在JSON中构造基本64字符串的方式在PHP方面似乎都不兼容。我做了一个测试,将JSON对象中的base 64编码字符串发送到PHP端,并将其与

中相同文件的base 64编码字符串进行比较。

https://www.browserling.com/tools/image-to-base64在if else语句中,例如 if 匹配,而 else 表示不匹配,令我惊讶的是它给了我else语句,表示它们与消息不匹配,因此我发现基本64字符串的方式是

在JavaScript端无法正确读取在JavaScript端编码和构造的

。 因此,任何照片查看器应用程序都无法读取照片。我假设其某些字符在JSON编码的base 64字符串中,但是来自if的两个比较字符串

其他语句测试看起来完全一样,所以我通过谷歌搜索了一个 可以在客户端转义特殊字符的方法,我发现了这种方法 调用encodeURIComponent();它会转义特殊字符,但对于URL,所以我很好地说

当我在JSON对象的编码基数64字符串上使用该字符串时,令我惊讶的是,它成功使基数64字符串在PHP服务器端可以理解,并且我能够毫无问题地查看照片

这是我的工作示例

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>

所以我现在的问题是,如果我尝试使用encodeURIComponent();以64位字符串编码的视频上的视频方法,它给了我这个错误

未捕获的RangeError:无效的字符串长度

因此,我需要找到另一种方法来使客户端的JSON对象中的已编码基数64字符串中的字符转义,以使其在PHP方面可理解,换句话说,就像encodeURIComponent()一样;而不是URL,而是客户端上的base 64编码字符串,无论客户端的base 64编码字符串有多大。