文件上传应用程序从PHP文件返回内部服务器错误

时间:2015-07-30 05:26:51

标签: php ios swift

我正在尝试在Swift中构建一个上传iOS应用的简单文件,但在点击上传图片按钮后,在控制台中不断收到以下内部服务器错误:

********* response = <NSHTTPURLResponse: 0x7f95284b65c0> { URL: http://website.com/upload.php } { status code: 500, headers {
    Age = 0;
    "Cache-Control" = "max-age=0";
    Connection = "keep-alive";
    "Content-Length" = 655;
    "Content-Type" = "text/html; charset=iso-8859-1";
    Date = "Thu, 30 Jul 2015 04:58:50 GMT";
    Expires = "Thu, 30 Jul 2015 04:58:50 GMT";
    "X-Cache" = MISS;
    "X-Varnish" = 107809910;
} }
********* response data = <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at 
 no-reply@x10hosting.com to inform them of the time this error occurred,
 and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>

这是我的Swift View Controller代码:

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    @IBOutlet weak var myImageView: UIImageView!
    @IBOutlet weak var myActivityIndicator: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func selectPhotoPressed() {
        var myPickerControl = UIImagePickerController()
        myPickerControl.delegate = self
        myPickerControl.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
        self.presentViewController(myPickerControl, animated: true, completion: nil)
    }

    @IBAction func uploadImagePressed() {
        myImageUploadRequest()
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        myImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    func myImageUploadRequest()
    {
        let myURL = NSURL(string: "http://website.com/upload.php");
        let request = NSMutableURLRequest(URL: myURL)
        request.HTTPMethod = "POST"

        let param = [
            "firstName": "John",
            "lastName": "Smith",
            "userID": "1"
        ]
        let boundary = generateBoundaryString()
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        let imageData = UIImageJPEGRepresentation(myImageView.image, 1)
        if (imageData == nil) { return; }
        request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData, boundary: boundary)

        myActivityIndicator.startAnimating();

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            if error != nil {
                println("error=\(error)")
                return
            }

            // print out response object
            println("********* response = \(response)")

            // print out response bdoy
            let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("********* response data = \(responseString)")

            dispatch_async(dispatch_get_main_queue(), {
                self.myActivityIndicator.stopAnimating()
                self.myImageView.image = nil
            });
        }

        task.resume()
    }

    func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
        var body = NSMutableData();
        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString("-\(boundary)\r\n")
                body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString("\(value)\r\n")
            }
        }

        let filename = "user-profile.jpg"
        let mimetype = "image/jpg"

        body.appendString("--\(boundary)\r\n")
        body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
        body.appendString("Content-Type: \(mimetype)\r\n\r\n")
        body.appendData(imageDataKey)
        body.appendString("\r\n")

        body.appendString("--\(boundary)--\r\n")
        return body
    }

    func generateBoundaryString() -> String {
        return "Boundary-\(NSUUID().UUIDString)"
    }
}

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

以下是后端upload.php文件:

<?php
$firstName = $_REQUEST["firstName"];
$lastName = $_REQUEST["lastName"];
$userID = $_REQUEST["userID"];

$target_dir = "uploads";
if (!file_exists($target_dir))
    mkdir($target_dir, 0777, true);

$target_dir .= "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["files"]["tmp_name"], $target_dir)) {
    echo json_encode([
        "Message" => "The file " . basename($_FILES["file"]["name"]) . "has been uploaded.",
        "Status" => "OK",
        "userID" => $_REQUEST["userID"]
    ]);
} else {
    echo json_encode([
        "Message" => "Sorry, there was an error uploading your file.",
        "Status" => "Error",
        "userID" => $_REQUEST["userID"]
    ]);
}
?>

我不确定这里有什么问题。为了排除故障,我向upload.php添加了ini_set('display_errors', 1);以及将文件的更改权限添加到777,但是继续在控制台中获取该消息。但是,如果我只是在浏览器中转到http://website.com/upload.php,我会收到{"Message":"Sorry, there was an error uploading your file.","Status":"Error","userID":null}

1 个答案:

答案 0 :(得分:2)

修复边界createBodyWithParameters上的破折号,如下所示:

func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
        let body = NSMutableData();

        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString("--\(boundary)\r\n") // <----- "--" Double Dash
                body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString("\(value)\r\n")
            }
        }

        let filename = "user-profile.jpg"
        let mimetype = "image/jpg"

        body.appendString("--\(boundary)\r\n") // <----- "--" Double Dash
        body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
        body.appendString("Content-Type: \(mimetype)\r\n\r\n")
        body.appendData(imageDataKey)
        body.appendString("\r\n")

        body.appendString("--\(boundary)--\r\n") // <----- "--" Double Dash

        return body
    }