【问题标题】:Download & Upload zip file下载和上传 zip 文件
【发布时间】:2021-10-22 07:08:56
【问题描述】:

我正在尝试模仿以下卷曲:

curl -v -F file=@/Users/myuser/Downloads/shelly-homekit-Shelly25.zip http://10.0.1.7/update

为了使用 curl 命令,我下载了 zip 文件并将其保存到我的计算机中。

我的应用应该下载 zip 文件,将其存储到设备并上传到服务器。

我尝试将其作为文件和数据上传,但均未成功:

            let destination: DownloadRequest.Destination = { _, _ in
                let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
                let fileURL = documentsURL.appendingPathComponent("shelly-homekit-Shelly1PM.zip")

                return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
            }

            AF.download("https://rojer.me/files/shelly/shelly-homekit-Shelly1PM.zip", to: destination).response { response in
                debugPrint(response)

                if response.error == nil, let zipPath = response.fileURL?.path {
                    
                    let url = URL(string: zipPath)!

                    
                    let headers: HTTPHeaders = [
                        .contentType("multipart/form-data")
                    ]
                    
                    if let data = try? Data(contentsOf: url) {
                        AF.upload(data, to: "http://"+dev.ipAddress+"/update",headers: headers).responseDecodable(of: HTTPBinResponse.self) { response in
                            debugPrint(response)
                        }
                    }
                }
            }

我收到以下错误:

感谢您的帮助

【问题讨论】:

  • 你检查过端点的ssl证书是否可信吗?
  • 我相信下载很顺利,上传服务器是一个仅使用 http 的物联网设备
  • 请求指向 TLS 安全资源? https://rojer.me/files/shelly/s...?
  • 从 safari 我可以看到网站证书,如果你的意思是这样的话
  • 您是否在 Info.plist 中设置了“NSAppTransportSecurity”以允许使用“NSExceptionDomains”连接到您的域?

标签: ios swift alamofire alamofire-upload


【解决方案1】:

就像你在允许任意负载的 cmets 中提到的那样。见Transport security has blocked a cleartext HTTP。更多详情

【讨论】:

    【解决方案2】:

    这没有帮助:

    就像你在允许任意负载的 cmets 中提到的那样。请参阅传输安全性已阻止明文 HTTP。更多详情

    我设置了链接中提到的权限:

    Permission

    但出现以下错误:

    Error

    我还对我的代码进行了一些更改:

                    let destination: DownloadRequest.Destination = { _, _ in
                    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
                    let fileURL = documentsURL.appendingPathComponent("shelly-homekit-Shelly1PM.zip")
    
                    return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
                }
    
                AF.download("https://rojer.me/files/shelly/shelly-homekit-Shelly1PM.zip", to: destination).response { response in
                    //debugPrint(response)
    
                    if response.error == nil {
                        AF.upload(response.fileURL!, to: "http://"+dev.ipAddress+"/update").responseDecodable(of: HTTPBinResponse.self) { response_up in
                            debugPrint(response_up)
                        }
                    }
                }
    

    【讨论】:

    • 是否有可能您的文件服务器在本地工作而应用程序无法真正访问它?
    • 服务器是本地连接的物联网设备,但应用可以访问
    • 254903752716 mgos_http_server.c:180 0x3fff62b4 HTTP 连接来自 10.0.1.167:59908 254903924124 mgos_http_server.c:180 0x3fff62b4 HTTP 连接来自 10.0.1.167:59909
    【解决方案3】:

    我使用 Wireshark 嗅探 curl 命令发送的请求:

    POST /update HTTP/1.1
    Host: 10.0.1.10
    User-Agent: curl/7.64.1
    Accept: */*
    Content-Length: 988427
    Content-Type: multipart/form-data; boundary=------------------------c67b500e63a02f3d
    Expect: 100-continue
    
    
    
    --------------------------c67b500e63a02f3d
    Content-Disposition: form-data; name="file"; filename="shelly-homekit-Shelly25.zip"
    Content-Type: application/octet-stream
    

    不确定如何将其转换为 AF 代码并将 fileData 添加到请求中,它应该是一个 POST 请求,我相信以下代码会创建正确的 http 正文:

                    let boundary = "Boundary-\(UUID().uuidString)"
    
                    let headers: HTTPHeaders = [
                        .contentType("multipart/form-data; boundary=\(boundary)")
                    ]
    
                    let parameters = [
                      [
                        "key": "file",
                        "value": "shelly-homekit-Shelly25.zip",
                        "type": "application/octet-stream",
                        "src":response.fileURL!.path
                      ]] as [[String : Any]]
    
                    var body = ""
                    for param in parameters {
                        let paramName = param["key"]!
                        body += "--\(boundary)\r\n"
                        body += "Content-Disposition:form-data; name=\"\(paramName)\""
                        body += "\r\nContent-Type: \(param["contentType"] as! String)"
                        //let paramSrc = param["src"] as! String
                        let paramValue = param["value"] as! String
                        let paramType = param["type"] as! String
                        //let fileData = try? NSData(contentsOfFile:paramSrc, options:[]) as Data
                        body += "; filename=\"\(paramValue)\"\r\n" + "Content-Type: " + paramType
                    }
                    let postData = body.data(using: .utf8)
    

    【讨论】:

      【解决方案4】:

      以下代码有效:

              let data = try? NSData(contentsOf: URL(string:str)!) as Data
          
              AF.upload(multipartFormData: { multipartFormData in
                  multipartFormData.append(data!,withName: "file",fileName: file_name ,mimeType: "application/octet-stream")
              }, to: "http://"+dev.ipAddress+"/update")
                  .response { response in
                      if response.response?.statusCode != 200 {
                          devicesUpdateError.append(dev.name)
                      }
                  }
      

      【讨论】:

        猜你喜欢
        • 2017-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        相关资源
        最近更新 更多