将base64编码的图像字符串POST到PHP

3
我已经阅读了许多文章并观看了一些视频。
问题:我无法将base64字符串图像作为POST请求发送到PHP服务器并保存到MySQL数据库中,而不会出现损坏。
我的尝试:我尝试传递像传递字符串或整数一样的图像的base64编码字符串作为POST参数。我验证了POST数据成功传输到PHP服务器,并且它被保存在数据库中。然而,当我提取base64编码字符串并解码以便可以在浏览器中呈现图像时,它不起作用。它只显示一个损坏的图像链接,而不是图像。似乎在POST过程中发生了某些破坏数据的情况。我这么说是因为我直接从Xcode的println()语句中复制了base64字符串,并将其粘贴到PHP文件中,其中它被解码并完美地显示。我能够完美地上传来自我的Android应用程序的图像的base64字符串。问题似乎出在我在Swift中的做法上。
经过一些研究,我发现可能需要在图像参数周围指定边界。但是我不确定,因为我不知道是否仅需要在直接发送图像文件时指定边界,还是在发送图像的base64编码字符串时也需要边界。
请问有人能告诉我在将base64编码字符串参数发送到PHP服务器之前是否需要设置边界?我可能做错了什么吗?
 let image: UIImage = imgProfilePic.image!

    let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(0.1, 0.1))
    let hasAlpha = false
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    var imageData = UIImageJPEGRepresentation(scaledImage, 0.9)
    let base64String = imageData.base64EncodedStringWithOptions(.allZeros)

    var cd = CoreDataUser(pstrContext: "this")

    var params = "strUsername=" + cd.getUsername()
    params = params + "&strPassword=" + cd.getPassword()
    params = params + "&blbProfilePic=" + base64String

一个base64编码的字符串可能包含+字符,PHP会将其替换为空格字符。 - findall
有没有办法防止这种情况发生? - play2win
好的。我会看看是否能找到如何实现那个的方法。感谢您的回复。 - play2win
请查看https://dev59.com/CGUq5IYBdhLWcg3wF8hQ#14803292。 - Rob
我做到了,而且它起作用了!你真是太棒了。我对这个网站还不太熟悉。有没有什么办法可以让我为正确的答案给你点赞? - play2win
1个回答

1

早些时候我向您介绍了https://dev59.com/CGUq5IYBdhLWcg3wF8hQ#14803292,其中展示了一种相对有限且战术性的解决方案来处理base-64字符串中的+字符。这包括将+字符替换为%2B

但我注意到您还在参数中包含用户名和密码。这表明您真正需要一个更通用的解决方案,即对所有保留字符进行百分号编码。如果不这样做,如果密码包含保留字符(例如+&),则此方法将无法正常工作。

提交此类参数时,应对值进行百分号编码。例如,您可以定义一个字符集,仅包括“未保留”的字符(由RFC 3986定义),即字母数字字符加上-._~

extension NSCharacterSet {
    class func URLQueryValueAllowedCharacterSet() -> NSCharacterSet {
        return NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~")
    }
}

然后你可以做像这样的事情:
func percentEscapeString(string: String) -> String {
    return string.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryValueAllowedCharacterSet())!
}

或者,如果你喜欢旧的CFURLCreateStringByAddingPercentEscapes函数,你可以这样做:

func percentEscapeString(string: String) -> String {
    return CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
        string,
        nil,
        ":/?@!$&'()*+,;=",
        CFStringBuiltInEncodings.UTF8.rawValue) as! String;
}

前面的例子更加直观,但是后面的方法稍微更加高效一些。
不管你采用哪种实现方式,你现在可以使用该函数对字符串进行百分号编码转义。
let params = "strUsername=" + percentEscapeString(cd.getUsername()) +
    "&strPassword=" + percentEscapeString(cd.getPassword()) +
    "&blbProfilePic=" + percentEscapeString(base64String)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接