【问题标题】:Data loss when uploading image data to PHP-Server将图像数据上传到 PHP-Server 时数据丢失
【发布时间】:2022-01-25 02:00:20
【问题描述】:

我有一个 iOS 应用程序,它应该通过 POST 请求将图像数据上传到我在 Nginx 上的 php 服务器。我可以上传数据,但是当我下载后,上传的文件已损坏且较小,无法打开。

我已将 post_max_size、max_input_vars 和 upload_max_filesize 的值更改得足够高,并正确设置了所有权限。

这是我的代码:

应用:

DispatchQueue.global().async {
    let url = "url to upload.php"
    
    var urlComponents = URLComponents(string: url!)
    urlComponents.queryItems = [
        URLQueryItem(name: "filetype", value: "img")
    ]

    var request = URLRequest(url: urlComponents.url!)
    request.httpMethod = "POST"

    let boundary = UUID().uuidString
    let contentType = "multipart/form-data; boundary=\(boundary)"

    var body = Data()

    body.append("--\(boundary)\r\n".data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"username\"\r\n\r\n".data(using: .utf8)!)
    body.append("\(username)\r\n".data(using: .utf8)!)
            
    body.append("--\(boundary)\r\n".data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"image-upload\"; filename=\"img.jpg\"".data(using: .utf8)!)
    body.append("Content-Type: image/jpeg".data(using: .utf8)!)
    body.append(imageData) // 2735963 bytes

    body.append("\r\n--\(boundary)--".data(using: .utf8)!)

    request.setValue(contentType, forHTTPHeaderField: "Content-Type")

    request.httpBody = body

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
                
            if error != nil {
                print(error!.localizedDescription)
                return
            }
                
                
            let responseString = String(data: data!, encoding: .utf8)
            print(responseString!) // final data stored on server: 2734537 bytes

                
    }
    task.resume()
}

PHP:

<?php

$user = $_POST['username'];///I need this for the path
$username = str_replace(array("\r", "\n", "'"), '', $user);
$type = $_GET['filetype'];

if ($type == "img")
{
    $path = "path to save img.jpg";
    $image = $_FILES['image-upload']['tmp_name'];

    if (move_uploaded_file($image, $path)) {
        echo "Success";
    }
    else
    {
        echo "Failed";
    }
}

?>

有什么问题吗?

【问题讨论】:

  • 在文本编辑中打开图像并检查内容。我的猜测是这是一条错误消息。您的服务器上是否打开了 PHP 错误报告?
  • @ChrisHaas 图像的文本文件只是看起来是有线的文本元素,没有错误消息,PHP 错误报告也没有显示任何错误。文件大小仅减少约 500 到 1000 KB。
  • @Rob 我将它与imageData 的字节数进行比较。我使用 UIImage(named: "")!.pngData()! 准备数据。例如,此数据的字节数为2735963 字节,而在服务器上仅为2734537 字节。是的,它正在报告成功。我也试过不设置Content-Length,但它没有改变任何东西。
  • 哦,抱歉,不,我正在使用 UIImage(named: "")!.jpeg(compressionQuality: 1.0)!" 创建 jpeg 数据
  • @Rob 谢谢,您链接的文章中的代码对我有用!

标签: php swift http nginx


【解决方案1】:

Content-Type: image/jpeg 后面的\r\n\r\n 不见了。

例如:

body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)

你可能在最终边界之后也需要它:

body.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)

另外,我们一般不设置Content-Length。让URLSession 为你做这件事。

请参阅 https://stackoverflow.com/a/26163136/1271826 或考虑使用像 Alamofire 这样的库,它可以让您摆脱准备多部分请求的麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    相关资源
    最近更新 更多