3

iPhoneアプリからNodejsとExpressを実行しているサーバーに画像と付随するメタデータを投稿しようとしています。REST クライアントを使用してブラウザーから投稿を実行すると、サーバー コードは正常に動作します。ただし、Objective C コードから同じポストを実行すると、サーバーで次のエラーが発生します。誰かが私が間違ったことを見つけることができますか? 私の調査によると、Express の Formidable ライブラリは、エンコーディングと境界に注意が必要です。回避策 (UTF8 を使用しないなど) を試しましたが、それでも問題は解決しません。さらに、私の調査では、リクエストでフィールドの 1 つに名前を付けるのを忘れると、この問題が発生する可能性があることが示唆されています。それも問題ではないようです。

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 に答える