3

我正在尝试将图像和随附的元数据从 iPhone 应用程序发布到运行 Nodejs 和 Express 的服务器。当我使用 REST 客户端从浏览器执行帖子时,我的服务器代码工作正常。但是,从 Objective C 代码执行的相同帖子会导致服务器上出现以下错误。有人能发现我做错了什么吗?我的研究表明,Express 中的强大库对编码和边界很挑剔。我尝试了解决方法(例如不使用 UTF8),但问题仍然存在。我的研究进一步表明,如果您忘记命名请求中的某个字段,则可能会出现此问题。这似乎也不是问题。

Error: parser error, 0 of 1448 bytes parsed
at IncomingForm.write (/home/ec2-user/babel-match-server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js:145:17)
at IncomingMessage.<anonymous> (/home/ec2-user/babel-match-server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js:95:12)
at IncomingMessage.emit (events.js:67:17)
at HTTPParser.onBody (http.js:115:23)
at Socket.ondata (http.js:1387:22)
at TCP.onread (net.js:354:27)

这是我执行 HTTP Post 的 Objective C 代码:

-(void) postImageToServer:(NSString *)imageFileName andImage:(NSData *)image {

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSString *user = [defaults objectForKey:@"babelMatchUser"];
NSString *lang = [defaults objectForKey:@"learnLanguage"];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://myserver.compute-1.amazonaws.com:3000/image?"]];
[request setHTTPMethod:@"POST"];
NSString *boundary = [[NSProcessInfo processInfo] globallyUniqueString];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body = [NSMutableData data];

// file
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n", imageFileName] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[NSData dataWithData:image]];
[body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];

// length
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"size\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%i",image.length] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];

// image name
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"imageFileName\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:imageFileName] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];


// language
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userLanguagePref\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithString:lang] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];

// user
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"user\"\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithString:user] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSASCIIStringEncoding]];

// close form
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSASCIIStringEncoding]];

// set request body
[request setHTTPBody:body];

//bon voyage
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
}

在服务器上,我使用以下代码处理帖子:

    } else if (req.method == 'POST') {
    // Check body.length for flood attack or faulty client
    var imageFileName = req.body.imageFileName; //imageFileName must match actual file name or app will crash
    var user = req.body.user;
    var usrLanguagePref = req.body.userLanguagePref;
    //model.saveImageMetaData(imageFileName, user, usrLanguagePref);
    if (req.files) {

        var image = req.files.image;
        var tempPath = image.path;
        var originalImage = image.name;
        var newImage = originalImage.split('.', 1) + '_150x150.' + originalImage.split('.')[1];
        var s3Headers = {
            'Content-Type': image.type,
                'x-amz-acl': 'public-read'
        };
        var dst;

        model.saveImageData(tempPath, originalImage, s3Headers, function () {
            var src = tempPath;
            dst = path.dirname(tempPath) + "/" + newImage;
            model.resizeImage(src, dst, function () {
                model.saveImageData(dst, newImage, s3Headers, function () {
                    res.send(200);
                });
            });
        });

    }
}
4

1 回答 1

1

几个建议。

  1. 我认为长度必须在帖子中的文件数据之前。
  2. 您能否提供实际从 objc 发送的 POST 数据的链接或示例?这将有助于解决数据格式的问题。
于 2012-11-21T03:21:30.630 回答