Sending audio from a Swift App to PHP Server, and somewhere the audio is lost

后端 未结 2 1287
攒了一身酷
攒了一身酷 2021-01-06 18:58

I am making an App in Swift that records some audio and then sends that recording to my PHP server.

The App records the audio clip fine (it can be played back with n

2条回答
  •  半阙折子戏
    2021-01-06 19:48

    Your PHP code is mostly fine. The $_FILES part is OK, but php://input is not available with enctype="multipart/form-data".

    The problem is with how you are generating the HTTP request in your Swift code. Mainly the HTTP headers. When creating the headers for multipart data, the pattern is this (if we choose AAAAA to be our boundary):

    • Our chosen boundary: "AAAAA"
    • Content Type = "multipart/form-data;boundary=AAAAA"
    • Beginning Bounary = --AAAAA
    • Ending Boundary = --AAAAA--

    So by fixing up your code a little bit:

    // This was your main problem
    let boundary = "--------14737809831466499882746641449----"
    let beginningBoundary = "--\(boundary)"
    let endingBoundary = "--\(boundary)--"
    let contentType = "multipart/form-data;boundary=\(boundary)"
    
    // recordedFilePath is Optional, so the resulting string will end up being 'Optional("/path/to/file/filename.m4a")', which is wrong.
    // We could just use currentFilename if we wanted
    let filename = recordedFilePath ?? currentFilename
    var header = "Content-Disposition: form-data; name=\"\(currentFilename)\"; filename=\"\(recordedFilePath!)\"\r\n"
    
    var body = NSMutableData()
    body.appendData(("\(beginningBoundary)\r\n" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData((header as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData(("Content-Type: application/octet-stream\r\n\r\n" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData(recording!) // adding the recording here
    body.appendData(("\r\n\(endingBoundary)\r\n" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
    
    var request = NSMutableURLRequest()
    request.URL = sendToURL
    request.HTTPMethod = "POST"
    request.addValue(contentType, forHTTPHeaderField: "Content-Type")
    request.addValue(recId, forHTTPHeaderField: "REC-ID") // recId is defined elsewhere
    request.HTTPBody = body
    

    In case you run into things like this again, when debugging networking code like this, I like to use tools that let me inspect the HTTP Network data being transferred. I personally like HTTPScoop because its simple, but you can also use BurpSuite or Charles

    I just ran your code through, and compared the HTTP traffic with what happened when I made the request with curl

    curl -X POST http://localhost/\~cjwirth/catch.php -F "file=@Untitled.m4a"
    

提交回复
热议问题