UIImagePNGRepresentation 导致 HTTP 错误 403
UIImagePNGRepresentation causes HTTP error 403
我今天遇到了一个非常特殊的问题。我在 iOS 中创建了 multipart/form-data header,然后将其发送到我的网络服务器上的 PHP 脚本。它仅使用字符串作为数据时工作正常,但是当我尝试将图像附加到 header 时,它 returns 403。这是尝试连接的函数:
func uploadImage(image: UIImage) {
var url: NSURL = NSURL(string: "https://example.com/uploadPicture.php")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
var boundary = NSString(format: "dsfghjkergsalkj")
var contentType = NSString(format: "multipart/form-data; boundary=%@", boundary)
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 60
var body = NSMutableData()
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Disposition: form-data; name=\"image-name\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("yay".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Type: image/png\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Transfer-Encoding: binary\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Disposition: form-data; name=\"profile-img\"; filename=\"profile.png\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSData(data: UIImagePNGRepresentation(image)))
//println(NSData(data: UIImagePNGRepresentation(image)))
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
let task = NSURLSession(configuration: .defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue()).dataTaskWithRequest(request) {
data, response, error in
if (error != nil) {
println("Error Submitting Request: \(error)")
return
}
var err: NSError?
var userData: [String: String]!
userData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? [String: String]
if(userData != nil) {
println(data)
println(userData)
} else {
println(data)
println("No data recieved.")
}
}
task.resume()
}
它应该 return 一个 JSON 关联数组,在键 'data' 下有 'true' 或 'false',如下所示。
if(isset($_FILES['profile-img'])) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);
相反,它 return 是一长串十六进制字节,即 403 禁止页面。
注释掉 body.appendData(NSData(data: UIImagePNGRepresentation(image)))
允许连接工作。
这可能是什么原因造成的?我已经尝试了我能想到的一切。
编辑:这是完整的 PHP 页面,不多。
<?php
error_reporting(E_ALL);
ini_set('display errors', 1);
if(isset($_FILES['profile-img'])) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);
/*$uploaddir = './uploads/';
$file = basename($_FILES['profile_img']['name']);
$uploadfile = $uploaddir . $file;
if (move_uploaded_file($_FILES['profile_img']['tmp_name'], $uploadfile)) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);*/
?>
您可能没有构建 PHP 正确解码的 MIME 多部分提交。 The spec for these is here.
- 每 header 行后面必须有一个
CRLF
序列。您可以通过以 \r\n
结束 header 字符串来实现此目的。在最后的 header 行之后和每个部分的数据之前应该有一个额外的 CRLF
序列。
- 您的二进制部分(文件)没有指定编码。默认情况下,规范采用“7BIT”编码,原始二进制文件不是其子集。尝试将 header
Content-Transfer-Encoding: binary
添加到此部分。
- 不一定是问题,但边界字符串通常是一个较长的字符串,包括一堆随机字符以避免与任何实际数据冲突。你的短星号序列对此不是特别强烈。
我今天遇到了一个非常特殊的问题。我在 iOS 中创建了 multipart/form-data header,然后将其发送到我的网络服务器上的 PHP 脚本。它仅使用字符串作为数据时工作正常,但是当我尝试将图像附加到 header 时,它 returns 403。这是尝试连接的函数:
func uploadImage(image: UIImage) {
var url: NSURL = NSURL(string: "https://example.com/uploadPicture.php")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
var boundary = NSString(format: "dsfghjkergsalkj")
var contentType = NSString(format: "multipart/form-data; boundary=%@", boundary)
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 60
var body = NSMutableData()
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Disposition: form-data; name=\"image-name\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("yay".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Type: image/png\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Transfer-Encoding: binary\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Disposition: form-data; name=\"profile-img\"; filename=\"profile.png\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSData(data: UIImagePNGRepresentation(image)))
//println(NSData(data: UIImagePNGRepresentation(image)))
body.appendData(NSString(format: "--%@\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
let task = NSURLSession(configuration: .defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue()).dataTaskWithRequest(request) {
data, response, error in
if (error != nil) {
println("Error Submitting Request: \(error)")
return
}
var err: NSError?
var userData: [String: String]!
userData = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? [String: String]
if(userData != nil) {
println(data)
println(userData)
} else {
println(data)
println("No data recieved.")
}
}
task.resume()
}
它应该 return 一个 JSON 关联数组,在键 'data' 下有 'true' 或 'false',如下所示。
if(isset($_FILES['profile-img'])) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);
相反,它 return 是一长串十六进制字节,即 403 禁止页面。
注释掉 body.appendData(NSData(data: UIImagePNGRepresentation(image)))
允许连接工作。
这可能是什么原因造成的?我已经尝试了我能想到的一切。
编辑:这是完整的 PHP 页面,不多。
<?php
error_reporting(E_ALL);
ini_set('display errors', 1);
if(isset($_FILES['profile-img'])) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);
/*$uploaddir = './uploads/';
$file = basename($_FILES['profile_img']['name']);
$uploadfile = $uploaddir . $file;
if (move_uploaded_file($_FILES['profile_img']['tmp_name'], $uploadfile)) {
$arr = ['data': 'true'];
} else {
$arr = ['data': 'false'];
}
echo json_encode($arr);*/
?>
您可能没有构建 PHP 正确解码的 MIME 多部分提交。 The spec for these is here.
- 每 header 行后面必须有一个
CRLF
序列。您可以通过以\r\n
结束 header 字符串来实现此目的。在最后的 header 行之后和每个部分的数据之前应该有一个额外的CRLF
序列。 - 您的二进制部分(文件)没有指定编码。默认情况下,规范采用“7BIT”编码,原始二进制文件不是其子集。尝试将 header
Content-Transfer-Encoding: binary
添加到此部分。 - 不一定是问题,但边界字符串通常是一个较长的字符串,包括一堆随机字符以避免与任何实际数据冲突。你的短星号序列对此不是特别强烈。