0

nodejs を使用してサーバーを実装し、ファイルのアップロードを処理するために multer を使用しました。

Postman を使用してファイルをアップロードすると、ファイルが正常にアップロードされ、コンソール ログ "upload image api" も表示されます。

ただし、Swift を使用して iOS からファイルをアップロードすると、ファイルも正常にアップロードされますが、コンソール ログ「アップロード イメージ API」と「フォーム解析が完了しました」は表示されません。これは、コールバック onParseEnd が呼び出されないことを意味します。これが、そこでフリーズし、「画像 API のアップロード」部分に移動しない理由だと思います。

iOS を使用してファイルをアップロードするときに onParseEnd が呼び出されないのはなぜですか? Postman を使用すると、すべてがうまくいきます。

Nodejs と Multer:

router.post('/upload', multer({
  dest: './public/uploads/user/',
  onFileUploadStart: function (file,req,res) {
    console.log(file.originalname + ' is starting ...')
    return true;
  },
  onFileUploadComplete: function (file) {
    console.log(file.fieldname + ' uploaded to  ' + file.path)
  },
  onParseStart: function () {
    console.log('Form parsing started at: ', new Date())
  },
  onParseEnd: function (req, next) {
    console.log('Form parsing completed at: ', new Date());
    // call the next middleware
    next();
    }
}), function(req,res,next){
    console.log("upload image api");

});

iOS 迅速:

var session = NSURLSession.sharedSession()
    let url = NSURL(string:url)
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = method
    request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")
    request.setValue("Cache-Control", forHTTPHeaderField: "no-cache")

    // set Content-Type in HTTP header

    let boundaryConstant = "Boundary-\(NSUUID().UUIDString)";
    let contentType = "multipart/form-data; boundary=\(boundaryConstant)"

    request.setValue(contentType, forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let filename = "image.jpg"
    var body = NSMutableData()
    body.appendString("--\(boundaryConstant)\r\n")
    body.appendString("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n")
    body.appendString("Content-Type: \(dataType)\r\n\r\n")
    body.appendData(data)
    body.appendString("\r\n")
    body.appendString("--\(boundaryConstant)\r\n")
    request.HTTPBody = body

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        println("Response: \(response)")
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Body: \(strData)")
        var err: NSError?
        var statusCode : Int = (response is NSHTTPURLResponse) ? (response as! NSHTTPURLResponse).statusCode : 404

        var json : NSDictionary?
        if(statusCode == 204){
            json = NSDictionary()
        }else{
            json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
        }

        // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
        if((err != nil)) {
            println(err!.localizedDescription)
            let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("Error could not parse JSON: '\(jsonStr)'")
            completed(succeeded: false, data: nil, statusCode: statusCode)
        }
        else {
            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                completed(succeeded: true, data: json, statusCode: statusCode)
                return
            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
                println("Error could not parse JSON: \(jsonStr)")
                completed(succeeded: false, data: nil, statusCode: statusCode)
            }
        }
    })

    task.resume()

以下は、上記の迅速なコードで使用される appendString 関数です。

func appendString(string: String) {
    let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
    appendData(data!)
}
4

1 に答える 1

0

Alamofire を使用しましたが、問題はなくなりました。
https://github.com/Alamofire/Alamofire

Alamofire.upload(.POST, URLString: url, multipartFormData: { multipartFormData in
        multipartFormData.appendBodyPart(data: data, name: key, fileName: "image.jpg", mimeType: "image/jpg")
        }, encodingCompletion: { encodingResult in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.responseJSON { request, response, data, error in

                    println("Response: \(response)")
                    var json = data as? NSDictionary

                    println("Body: \(json)")
                    var statusCode : Int = (response != nil) ? response!.statusCode : 404
                    completed(succeeded: true, data: json, statusCode: statusCode)

                }
            case .Failure(let encodingError):
                completed(succeeded: false, data: nil, statusCode: 404)
            }
    })

前の方法が機能しない理由を誰かが知っている場合は、コメントを残してください。ありがとう。

于 2015-08-18T08:26:21.760 に答える