NSURLSession POST请求API

问题描述 投票:-2回答:1

我试图将图像上传为多部分表单数据,但我从服务器收到状态代码404的错误。任何人都可以指出我在做这个错误吗?

服务器接受“文件”作为我们上传的图像的关键。

这是我到目前为止所尝试的...

   public func UPLOADING(url: String,parameters: Dictionary<String,AnyObject>?,filename:String,image:UIImage, success:((NSDictionary) -> Void)!, failed:((NSDictionary) -> Void)!, errord:((NSError) -> Void)!) {
    let TWITTERFON_FORM_BOUNDARY:String = "AaB03x"
    let url = NSURL(string: url)!
    let request:NSMutableURLRequest = NSMutableURLRequest(url: url as URL, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 10)
    let MPboundary:String = "--\(TWITTERFON_FORM_BOUNDARY)"
    let endMPboundary:String = "\(MPboundary)--"
    //convert UIImage to NSData
    let data:NSData = UIImagePNGRepresentation(image)! as NSData
    let body:NSMutableString = NSMutableString();
    // with other params
    if parameters != nil {
        for (key, value) in parameters! {
            body.appendFormat("\(MPboundary)\r\n" as NSString)
            body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n" as NSString)
            body.appendFormat("\(value)\r\n" as NSString)
        }
    }
    // set upload image, name is the key of image
    body.appendFormat("%@\r\n",MPboundary)
    body.appendFormat("Content-Disposition: form-data; file=\"\(filename)\"\"\r\n" as NSString)
    body.appendFormat("Content-Type: image/png\r\n\r\n")
    let end:String = "\r\n\(endMPboundary)"
    let myRequestData:NSMutableData = NSMutableData();
    myRequestData.append(body.data(using: String.Encoding.utf8.rawValue)!)
    myRequestData.append(data as Data)
    myRequestData.append(end.data(using: String.Encoding.utf8)!)
    let content:String = "multipart/form-data; boundary=\(TWITTERFON_FORM_BOUNDARY)"
    request.setValue(content, forHTTPHeaderField: "Content-Type")
    request.setValue("\(myRequestData.length)", forHTTPHeaderField: "Content-Length")
    request.httpBody = myRequestData as Data
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {
        data, response, error in
        if error != nil {
            print(error!)
            errord(error! as NSError)
            return
        }
        print(response ?? "")
        do {
            let responseObject:[String:Any]? = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String:Any]
            if let responseDictionary = responseObject as NSDictionary? {
                success(responseDictionary)
            } else {
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }


    })
    task.resume()
    }

在viewDidload中,

let image = UIImage(named: "ed1.png",
                        in: Bundle(for: type(of: self)),
                        compatibleWith: nil)

    UPLOADING(url: "url-of-site", parameters: nil, filename: "ed1.png", image: image!, success: { (sucDict) in
        print(sucDict)
    }, failed: { (failedDict) in
        print(failedDict)
    }) { (error) in
        print(error.description)
    }
ios swift post image-uploading nsurlsession
1个回答
1
投票

我看到几个问题,主要是次要的:

  • 您的Content-Disposition:行缺少'name = file;'位。这是它无法正常工作的一个主要原因。
  • 你的边界太短(至少20个字符左右;上限是70个字符,你应该使用它们中的很大一部分)。短边界存在出现在您尝试发送的实际数据中的真实风险。
  • 您应该使用NSData来构建整个主体,而不是在最后一部分之前使用可变字符串。
  • 理想情况下,在执行此操作时,应检查边界是否出现在任何值中,如果是,则生成新边界并重新开始,直到成功为止。
  • 除非保证值为7位ASCII,否则Content-Type字段应该存在于每个部分,因为Content-Type提供字符编码(在本例中为UTF-8)。否则,可能会发生奇怪的事情。
  • 你应该在结束边界之后有一个尾随的CRLF,只是为了在调试时的可读性,尽管这不应该导致失败。
  • 最后,如果您要上传到Twitter等公共服务,则可能需要在URL或请求标头中添加某种API密钥,如果缺少该密钥,API可能会发出错误。

但没有一个合理地解释404错误。只有在脚本本身的路径错误时才应该发出。这可能是由某些微妙的原因引起的,例如iOS更喜欢通过IPv4上的IPv6地址访问服务器,并且Web服务器的IPv6端可能配置错误。或者它可能是错误的URL。无论哪种方式,调试的唯一方法是深入了解服务器日志并查看它尝试读取的文件,然后找出该文件不存在的原因。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.