本文介绍了无法将包含多部分/表单数据的图片上传到服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在multipart/form-data上阅读了很多主题.它仍然不起作用.我可以使用URLSession.shared.uploadTask将文件上传到服务器.

I've read quite a lot of topics here on multipart/form-data. It still doesn't work. I am able to upload a file to my server with URLSession.shared.uploadTask.

class MainViewController: UIViewController {
    @IBOutlet weak var pictureView: UIImageView!

    @IBAction func postTapped(_ sender: UIButton) {
        postData()
    }

    func postData() {
        var request = URLRequest(url: URL(string: "http://www.mywebsite.com/upload.php")!)
        request.httpMethod = "POST"
        request.timeoutInterval = 30.0

        guard let imageData = UIImagePNGRepresentation(pictureView.image!) else {
            print("oops")
            return
        }

        let uuid = UUID().uuidString
        let CRLF = "\r\n"
        let filename = uuid + ".png"   // file name
        let formName = uuid + ".png"   // file name in the form
        let type = "image/png"     // file type
        let titleData = "hoge"      // title
        let titleName = uuid + ".png"     // title name in the form
        let boundary = String(format: "----iOSURLSessionBoundary.%08x%08x", arc4random(), arc4random())
        var body = Data()
        // form data //
        body.append(("--\(boundary)" + CRLF).data(using: .utf8)!)
        body.append(("Content-Disposition: form-data; name=\"\(titleName)\"" + CRLF + CRLF).data(using: .utf8)!)
        body.append(titleData.data(using: .utf8)!)
        body.append(CRLF.data(using: .utf8)!)
        // file data //
        body.append(("--\(boundary)" + CRLF).data(using: .utf8)!)
        body.append(("Content-Disposition: form-data; name=\"\(formName)\"; filename=\"\(filename)\"" + CRLF).data(using: .utf8)!)
        body.append(("Content-Type: \(type)" + CRLF + CRLF).data(using: .utf8)!)
        body.append(imageData)
        body.append(CRLF.data(using: .utf8)!)
        // footer //
        body.append(("--\(boundary)--" + CRLF).data(using: .utf8)!)
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.setValue("\(body.count)", forHTTPHeaderField: "Content-Length")
        request.httpBody = body
        let session = URLSession(configuration: .default)
        session.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print(error)
            }
            if let respose = response {
                print(respose)
            }
        }
        .resume()
    }
}

PHP(索引处为upload.php)

PHP (upload.php at index)

$dir = __DIR__ . '/upload/';
$path = $dir . basename($_FILES['filename']['name']);

$data['result'] = 'failure';
if (move_uploaded_file($_FILES['filename']['tmp_name'], $path)) {
    chmod($path, 0777);
    $data['result'] = date("H:i:s") . ' ' . $_POST['title'] . ' success';
}

header('Content-Type: application/json');
echo json_encode($data);

上面的代码是我尝试过的许多版本之一.没有错响应显示状态码为200.但是服务器中没有文件.我不知道为什么它不起作用?与App Transport Security Settings无关.我还没有准备好使用Alamofire. Muchos Thankos.

The code above is one of many versions I have tried. There's no error. The response says the status code is 200. But there's no file in the server. I wonder why it doesn't work? It's not about App Transport Security Settings. I'm not ready to use Alamofire, yet. Muchos thankos.

推荐答案

我调试了您的代码,进行了简化,为清晰起见,将调试语句保留了下来.这是我想出的:

I debugged your code, simplified and left the debug statements in for clarity. Here is what I came up with:

func postData() {
    var request = URLRequest(url: URL(string: "http://localhost/uploadimages/uploadtry.php")!)
    request.httpMethod = "POST"
    request.timeoutInterval = 30.0

    guard let imageData = UIImagePNGRepresentation(pictureView.image!) else {
        print("oops")
        return
    }

    let CRLF = "\r\n"
    let filename = "user.png"
    let formName = "file"
    let type = "image/png"     // file type

    let boundary = String(format: "----iOSURLSessionBoundary.%08x%08x", arc4random(), arc4random())

    var body = Data()

    // file data //
    body.append(("--\(boundary)" + CRLF).data(using: .utf8)!)
    body.append(("Content-Disposition: form-data; name=\"\(formName)\"; filename=\"\(filename)\"" + CRLF).data(using: .utf8)!)
    body.append(("Content-Type: \(type)" + CRLF + CRLF).data(using: .utf8)!)
    body.append(imageData as Data)
    body.append(CRLF.data(using: .utf8)!)

    // footer //
    body.append(("--\(boundary)--" + CRLF).data(using: .utf8)!)
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    //TW debug the body data.
    let theString:NSString = NSString(data: body as Data, encoding: String.Encoding.ascii.rawValue)!
    print(theString)

    request.setValue("\(body.count)", forHTTPHeaderField: "Content-Length")

    request.httpBody = body
    let session = URLSession(configuration: .default)
    session.dataTask(with: request) { (data, response, error) in
        if let error = error {
            print(error)
        }
        if let respose = response {
            print(respose)
        }
        // TW
        if let data = data {
            // This gives us same as server log

            // You can print out response object
            print("******* response = \(String(describing: response))")

            print(data.count)
            // you can use data here

            // Print out reponse body
            let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
            print("****** response data = \(responseString!)")

        }

        }
        .resume()
}

提到的uploadtry.php

The mentioned uploadtry.php

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);

$dir = 'media';
$path = $dir . "/" . basename($_FILES['file']['name']);


$data['result'] = 'failure';
if (move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
    chmod($path, 0777);
    $data['result'] = ' success';
}

header('Content-Type: application/json');
echo json_encode($data);


?>

基本上,我在服务器上看到了这样的错误:

Basically I saw errors like this on the server:

Undefined index: filename in /pathtoserver/uploadimages/uploadtry.php on line 6

因此服务器无法理解您消息中的文件名.如果您没有服务器访问权限,则调试语句可帮助您在客户端查看错误.

So the server could not understand filename in your message.The debug statements help you to see the error also on the client side if you have no server access.

希望可以帮助您入门.

这篇关于无法将包含多部分/表单数据的图片上传到服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 02:02
查看更多