如何扩展 IOS SimpleURLConnections HTTP POST 以发送可由 CGI Perl 解码的说明
我想扩展名为 SimpleURLConnections 的示例 ios 代码。此示例代码可以使用 HTTP POST 上传文件。我已经使用 Perl 编写的 cgi 脚本启用了我的 apache Web 服务器,以接收处理 cgi 脚本并成功上传文件的 HTTP POST。我想做的扩展是添加上传文件的标题或描述。我尝试更新示例代码中的多部分表单数据并对我的 cgi 脚本进行相应更改以传输此描述,但失败了。 cgi 脚本无法使用名为 param() 的 cgi.pm 方法读取描述。我希望有人能提供帮助。以下是详细信息:
我修改之前的多部分表单数据如下所示(注意:SimpleURLConnections 例程在 Content-Type 和第二个边界之间动态插入图像文件):
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="fileContents"; filename="1234567/TestImage1.png"
Content-Type: image/png
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="uploadButton"
Upload File
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97--
我修改之后的多部分表单数据如下所示以下:
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="Title"; title="Hello World"
Content-Type: text/plain
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="fileContents"; filename="1234567/TestImage1.png"
Content-Type: image/png
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="titleButton"
my Title
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="uploadButton"
Upload File
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97--
我的 cgi 脚本如下所示:
#!/usr/bin/perl -wT
use strict;use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
my $upload_dir = "/Library/WebServer/Documents/upload";
my $query = new CGI;
my $title = $query->param("Title");
#if (!$title) {
# die "the title is $title. $!";
#}
if ( !$filename ) {
print $query->header ( );
die "There was a problem uploading your photo (try a smaller file). : $!";
exit;
}
...
open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
while ( <$upload_filehandle> ) {
print UPLOADFILE;
}
close UPLOADFILE;
此代码工作正常,上传的文件被写入 upload_dir。
但是,如果我取消注释那一小段代码:
if (!$title) {
die "the title is $title. $!";
}
脚本会因错误而终止,该错误表明 $title 没有值:
[Tue Sep 27 17:09:17 2011] [error] [client 10.0.1.2] [Tue Sep 27 17:09:17 2011] upload.cgi: Use of uninitialized value $title in print at /Library/WebServer/CGI-Executables/upload.cgi line 79.
那么,是我的多部分表单数据、cgi 脚本有问题,还是无法传递此数据在多部分表单数据中?还有其他方法吗?
谢谢
好的,在得到@AFresh1的帮助后,我发现了问题。问题在于如何创建多部分表单数据的细节。首先我会展示错误的方式。
NSString *title = @"Hello World";
bodySuffixStr = [NSString stringWithFormat: // create the footer for the POST message
@
"\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"titleButton\"\r\n"
"%@\r\n\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"uploadButton\"\r\n"
"\r\n"
"Upload File\r\n"
"--%@--\r\n"
"\r\n",
boundaryStr,
title,
boundaryStr,
boundaryStr
];
现在正确的方法(第 7 行的一个非常微妙的变化 - 移动了 CR/LF):
NSString *title = @"Hello World";
bodySuffixStr = [NSString stringWithFormat: // create the footer for the POST message
@
"\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"titleButton\"\r\n"
"\r\n%@\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"uploadButton\"\r\n"
"\r\n"
"Upload File\r\n"
"--%@--\r\n"
"\r\n",
boundaryStr,
title,
boundaryStr,
boundaryStr
];
I would like to extend the sample ios code called SimpleURLConnections. This sample code can upload a file using HTTP POST. I have enabled my apache web server with a cgi script written in Perl to receive the HTTP POST that addresses the cgi script and successfully uploads the file. The extension I would like to make is to add a title or description of the uploaded file. I have tried to update the multipart form data in the sample code and a corresponding change to my cgi script to transfer this description, but it is failing. The cgi script cannot read in the description using the cgi.pm method called param(). I'm hoping someone can help. Here are the details:
The multipart form data BEFORE my modification looks like the following (NOTE: the SimpleURLConnections routine inserts the image file between the Content-Type and the 2nd boundary on the fly):
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="fileContents"; filename="1234567/TestImage1.png"
Content-Type: image/png
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="uploadButton"
Upload File
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97--
The multipart form data AFTER my modification looks like the following:
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="Title"; title="Hello World"
Content-Type: text/plain
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="fileContents"; filename="1234567/TestImage1.png"
Content-Type: image/png
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="titleButton"
my Title
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97
Content-Disposition: form-data; name="uploadButton"
Upload File
--Boundary-D4AFFBA9-AD92-4697-9184-7BDA128C3B97--
My cgi script looks like the following:
#!/usr/bin/perl -wT
use strict;use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
my $upload_dir = "/Library/WebServer/Documents/upload";
my $query = new CGI;
my $title = $query->param("Title");
#if (!$title) {
# die "the title is $title. $!";
#}
if ( !$filename ) {
print $query->header ( );
die "There was a problem uploading your photo (try a smaller file). : $!";
exit;
}
...
open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
while ( <$upload_filehandle> ) {
print UPLOADFILE;
}
close UPLOADFILE;
This code works fine and the uploaded file gets written to the upload_dir.
But, if I uncomment that little block of code:
if (!$title) {
die "the title is $title. $!";
}
the script dies with an error that indicates that $title has no value:
[Tue Sep 27 17:09:17 2011] [error] [client 10.0.1.2] [Tue Sep 27 17:09:17 2011] upload.cgi: Use of uninitialized value $title in print at /Library/WebServer/CGI-Executables/upload.cgi line 79.
So, is the problem with my multipart form data, the cgi script, or is it not possible to pass this data in the multipart form data? Is there an alternate way?
Thanks
Ok, after getting help from @AFresh1, I found the problem. The problem was in the details of how the multipart form data was created. First I will show the wrong way.
NSString *title = @"Hello World";
bodySuffixStr = [NSString stringWithFormat: // create the footer for the POST message
@
"\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"titleButton\"\r\n"
"%@\r\n\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"uploadButton\"\r\n"
"\r\n"
"Upload File\r\n"
"--%@--\r\n"
"\r\n",
boundaryStr,
title,
boundaryStr,
boundaryStr
];
Now the correct way (a very subtle change in the 7th line - moved the CR/LF):
NSString *title = @"Hello World";
bodySuffixStr = [NSString stringWithFormat: // create the footer for the POST message
@
"\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"titleButton\"\r\n"
"\r\n%@\r\n"
"--%@\r\n"
"Content-Disposition: form-data; name=\"uploadButton\"\r\n"
"\r\n"
"Upload File\r\n"
"--%@--\r\n"
"\r\n",
boundaryStr,
title,
boundaryStr,
boundaryStr
];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信内容位于标题后面的空格中
并且在下一个边界之前不在标题属性中。部分标题是边界之后和空行之前的所有内容。
如果您想使用
$query->param('Title')
将“Hello World”放入 $title 中,我认为您将需要更多类似这样的内容(请注意,Content-type 默认为文本/清楚的):I believe the content goes in the space after the header
and before the next boundary not in a title attribute. The part header being everything after the boundary and before the blank line.
If you are want to get "Hello World" into $title using
$query->param('Title')
I think you will need something more like this (note that Content-type defaults to text/plain):