如何通过json发送base64编码的文件内容将文件上传内容插入数据库?

问题描述

从我的 PHP 页面,我将文件上传内容发送为

$imgData = addslashes(file_get_contents($_FILES['userImage']['tmp_name']));
$imgData= base64_encode($imgData);

然后将其发送到有效负载 - Python 中的 REST API

$call->send('{"payload" : { "dbstr" :"' . DEF_DB . '","tblCode" : "' . USE_INF . '","use_cod": "'.$use_cod.'","use_pas": "'.$use_pas.'","use_nam": "'.$use_nam.'","use_dob": "'.$use_dob.'","use_ema": "'.$use_ema.'","use_des": "'.$use_des.'","use_pfe": "'.$imgData.'"}');

然后在我的python代码中我是这样写的

use_pfe = item_dict['payload']['use_pfe']
imgdata1 = use_pfe.encode("utf-8")
imgdata2 = base64.b64decode(imgdata1)

现在我尝试使用 sql 将其插入到我的数据库中,其中图像列是二进制(blob)类型

cursUserAU.execute("insert into " + tblCode + " (use_cod,use_pass,use_nam,use_dob,use_email,use_desig,use_profile) values ('" + use_cod +"','"+ use_pas +"','"+ use_nam +"','"+ use_dob +"','"+ use_ema +"','"+ use_des +"',"+ imgdata2 +")")

但这以错误告终...我做对了吗?还是缺少任何部分?我不想将此文件保存在任何目录中,我只想将其直接保存在 db 中。请帮助我提供建议或任何资源。提前致谢。

更多详情如下

我正在使用 adsdb python 驱动程序连接优势数据库服务器数据库

在蟒蛇

connUserAU = adsdb.connect(DataSource=datasource,ServerType='3',UserID='adssys',Password='')
cursUserAU = connUserAU.cursor()
sql = "insert into " + tblCode + " (use_cod,use_profile) values (?,?,?)"
cursUserAU.execute(sql,(use_cod,use_pas,use_ema,use_des,imgdata))
connUserAU.commit()
cursUserAU.close()

use_profile 以上是 blob 列类型

这里是数据库列类型

use_cod Char( 10 ),use_pass Char( 10 ),use_nam Char( 30 ),use_dob Date,use_email Char( 50 ),use_desig Char( 30 ),use_profile Blob,user_gender Char( 1 ),use_profile2 CIChar( 50 )

解决方法

在您的 PHP 代码中,调用 file_get_contents($_FILES['userImage']['tmp_name']) 后,返回值是一个包含图像内容的字符串,它是二进制数据。您不应将这些内容当作实际字符进行转义。所以这一行应该是:

$imgData = file_get_contents($_FILES['userImage']['tmp_name']);

因此,在您的 Python 代码中,use_pfe 将是 base64 编码的图像。这将是一串 ASCII 字符。线...

imgdata1 = use_pfe.encode("utf-8")

... 将 use_pfe 转换为使用 utf-8 编码的字节字符串。但是,因为这是 Python 2,其中字节字符串与简单字符串(即类型 str 而不是 Unicode 字符串,即类型 unicode)和字符相同被编码的是来自 ASCII 字符集,它可以被编码成一个字节,你最终得到 imgdata1use_pfe 相同。实际上,该语句没有任何作用。但是,如果这是 Python 3,其中字节字符串,类型为 bytes,与字符串不同,字符串是 unicode 字符串,类型为 str,这一行将是不正确的:您需要将输入保留为输入 str 作为 next 行的输入,它将 base64 字符串转换回字节字符串。

综合起来:

PHP:

$imgData = file_get_contents($_FILES['userImage']['tmp_name']);
$imgData = base64_encode($imgData);

Python:

use_pfe = item_dict['payload']['use_pfe']
imgdata2 = base64.b64decode(use_pfe)

您应该使用 Prepared Statement 按如下方式进行表插入,这不仅简化了值的传递,而且还避免了在用户提供值时发生 SQL 注入攻击的可能性。下面参数的占位符是 ?,我认为它适用于您的数据库(对于 MySql 和 PostgreSQL 以及大多数其他关系数据库,请使用 %s)。

# make it more readable:
sql = "insert into " + tblCode + " (use_cod,use_pass,use_nam,use_dob,use_email,use_desig,use_profile) values (?,?,?)"
cursUserAU.execute(sql,(use_cod,use_pas,use_ema,use_des,imgdata2))

但是上面的原因是:

UnicodeDecodeError: 'ascii' 编解码器无法解码位置 0 中的字节 0xff:序号不在范围内(128)`

现在您必须提供表 tblCode 中每一列的完整描述,包括所使用的字符集。此外,打印出每个传递的参数,type(argument) 例如:

print type(use_cod),type(use_pas),type(use_nam),... type(imgdata2)

但为了节省时间,让我问一下问题的最可能原因:您是否对列 use_profile 使用了 BLOB 类型?

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...