快速多部分/表单数据上传,将字符串数组附加到正文(问题:数组作为字符串到服务器)

Posted

技术标签:

【中文标题】快速多部分/表单数据上传,将字符串数组附加到正文(问题:数组作为字符串到服务器)【英文标题】:Swift multipart/form-data upload with append String Array to body (Issue: Array goes as String to Server) 【发布时间】:2019-05-18 08:11:44 【问题描述】:

我尝试使用 Alamofire Swift 库在多部分请求中将字符串数组发送到服务器,我尝试了几种方法来对数组进行编码,但大多数时候它都是作为字符串发送的。谁能帮我这个。除了发送图像上传的数组和其他值对服务器正常。下面是我的代码。

var parameters: Parameters = [
        "UEmail": userObj.email,
        "UFirstName": fName,
        "ULastName": lName,
        "VisitedCountries": getVisitedCountryCodeList() //return String array
    ]

let headers: HTTPHeaders
    headers = ["Content-type": "multipart/form-data"]

    AF.upload(multipartFormData:  (multipartFormData) in
        for (key, value) in parameters 
            if let subArray = value as? NSArray 
                do 
                    if(key == "VisitedCountries")
                        let data = try JSONSerialization.data(withJSONObject: self.getVisitedCountryCodeList(), options: [])
                        multipartFormData.append(data, withName: "VisitedCountries" )
                    
                 catch 
                    print("error msg")
                
             else 
                multipartFormData.append((value as! NSString).data(using: String.Encoding.utf8.rawValue)!, withName: key )
            
        

        if(self.selectedProfileImage != nil)
            guard let imgData = self.selectedProfileImage.jpegData(compressionQuality: 2) else  return 
            multipartFormData.append(imgData, withName: "file", fileName: "image.jpeg", mimeType: "image/jpeg")
        

    ,usingThreshold: UInt64.init(),
      to: "\(Constants.SERVER_URL)\(Constants.USER_EDIT)",
      method: .post,
      headers: headers).response response in
        SVProgressHUD.dismiss()
        if(response.data != nil) 

            do 
                if let jsonData = response.data 
                    let parsedData = try JSONSerialization.jsonObject(with: jsonData) as! Dictionary<String, AnyObject>

                    print(parsedData)
                

             catch 
                print("error msg")
            
         else 
            print("user edit response2 \(response) end")
        
    

以上是我的 AF.upload 代码。数组追加是我有问题的部分。 这是数组附加代码。

//getVisitedCountryCodeList() returns string array  

let data = try JSONSerialization.data(withJSONObject: self.getVisitedCountryCodeList(), options: []) 
multipartFormData.append(data, withName: "VisitedCountries" )

我也试过下面的代码

multipartFormData.append(try JSONEncoder().encode(self.getVisitedCountryCodeList()), withName: key )

下面是服务器得到的,是字符串而不是数组

"VisitedCountries"=>"[\"ALG\",\"ARG\"]"

但我需要这样发送

"VisitedCountries"=> ["ALG","ARG"]

【问题讨论】:

它是键“VisitedCountries”下的字符串数组。您期望的格式是什么? "VisitedCountries"=> ["ALG","ARG"] 。我期待这个。特别是没有外部“[]”引号。 p.s- 我不是后端开发者@Losiowaty 【参考方案1】:

终于自己找到答案了,只需要对key值做个小技巧。下面是代码。

for code in self.getVisitedCountryCodeList()
    if let codeData = code.data(using: .utf8) 
        multipartFormData.append(codeData, withName: key+"[]" )
    

key+"[]""VisitedCountries[]" 是这里的技巧,它会自动将其捕获为数组并将下一个值添加到其中。

【讨论】:

【参考方案2】:

在我的情况下,接受的解决方案仅适用于发送数组中的一个对象。对于多个项目,数组需要以"code[]="ALG","ARG"" 发送。

接受的答案会生成多个数组,每个数组包含一项,例如:"code[]="ALG" "code[]="ARG""。对我有用的是首先生成所有数组对象的逗号分隔字符串,将其转换为 Data 并一次性将其附加到 MultiPartFormData。

替代代码:

        let key = "countryCodes"
        let array = ["ALG", "ARG"]
        let arrayString = array.joined(separator: ",")

        if let arrayData = arrayString.data(using: .utf8) 
            formData.append(arrayData, withName: key+"[]" )
        

【讨论】:

【参考方案3】:

在标题中将 Content-typemultipart/form-data 更改为 application/json。请求的Content-type 告诉服务器您以哪种格式发送数据。

let headers: HTTPHeaders = ["Content-type": "application/json"]

【讨论】:

我还需要上传一张图片。刚试过,还是一样:D @LahiruPinto 检查jpegData(compressionQuality:)compressionQuality - 表示为 0.0 到 1.0 之间的值

以上是关于快速多部分/表单数据上传,将字符串数组附加到正文(问题:数组作为字符串到服务器)的主要内容,如果未能解决你的问题,请参考以下文章

快速文件上传java rest api mimepull关闭问题与多部分表单数据

AFNetworking 2.0 多部分/表单数据上传到 mySQL

将数组附加到 FormData 并通过 AJAX 发送

通过压缩将HTTP发布多部分/表单数据流式传输并上传到存储中?

发布多部分表单数据问题

上传多部分表单数据时如何观察uploadProgress? [复制]