Целевая загрузка файла многостраничной формы с учетными данными пользователя

У меня есть следующий код в объекте C, который отлично подходит для загрузки файла через POST в node.js / formidable.

Однако я хотел бы включить учетные данные пользователя и дополнительные сведения о файле в этот запрос POST. Я просмотрел все и не смог найти примера, который позволил бы мне добиться этого.

Пожалуйста, посоветуйте, что мне нужно для достижения вышеуказанной цели.

Вот мой код в Objective C:

-(void) uploadToServer:(NSData*) mediaData
                         asType:(int) mediaType
                         asFile:(NSString*) saveFileAs{

    NSDictionary *params = @{@"subFolder"   : G_deviceName,
                             @"filename"    : saveFileAs
                             };

    NSString *boundary = [self generateBoundaryString];


        // configure the request

    NSString * urlForUploading = [NSString stringWithFormat:@"%@/upload",G_appServerURL ];

    NSURL *uploadToURL = [NSURL URLWithString:urlForUploading];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:uploadToURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    [request setHTTPMethod:@"POST"];

        // set content type

    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"];

        // create body

    NSData *httpBody = [self createBodyWithBoundary:boundary parameters:params mediaData:mediaData fieldName:@"fieldName"];

    self.session = [NSURLSession sharedSession];  // use sharedSession or create your own

    NSURLSessionTask *task = [self.session uploadTaskWithRequest:request fromData:httpBody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            NSLog(@"error = %@", error);
            [[NSNotificationCenter defaultCenter] postNotificationName:@"activeUpload" object:nil userInfo:nil];
            return;
        }
        else{
            NSLog(@"uploadToServer successful." );

            [[NSNotificationCenter defaultCenter] postNotificationName:@"activeUpload" object:nil userInfo:nil];
        }

        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"result = %@", result);
    }];
    [task resume];

}

- (NSData *)createBodyWithBoundary:(NSString *)boundary
                        parameters:(NSDictionary *)parameters
                         mediaData:(NSData*)mediaData
                         fieldName:(NSString *)fieldName
{
    NSMutableData *httpBody = [NSMutableData data];

        // add params (all params are strings)

    [parameters enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
        [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]];
        [httpBody appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]];
    }];

        // add image data

    NSString *formName = [parameters objectForKey:@"subFolder"];
    NSString *filename  = [parameters objectForKey:@"filename"];
    NSString *mimetype  = @"image/jpeg";  //[self mimeTypeForPath:path];

    [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", formName, filename] dataUsingEncoding:NSUTF8StringEncoding]];
    [httpBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8StringEncoding]];
    [httpBody appendData:mediaData];
    [httpBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

    [httpBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

    return httpBody;
}

- (NSString *)generateBoundaryString
{
    return [NSString stringWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDString]];

}

Вот код на сервере node.js, который получает этот запрос POST и сохраняет файл:

app.post ('/ upload', function (req, res) {

  var subFolder;

  // create an incoming form object
  var form = new formidable.IncomingForm();

  form.multiples = false;

  form.uploadDir = '/home/uploads'

  form.on('fileBegin', function(name, file) {

    console.log('entered fileBegin ... ');
      form.uploadDir = form.uploadDir + name;

  });

  // every time a file has been uploaded successfully, rename it to it's orignal name
  form.on('file', function(field, file) {
    fs.rename(file.path, path.join(form.uploadDir, file.name));

  });


    form.parse(req, function(err, fields, files) {
        if (err) 
          console.log("In form.parse, error occured : " + util.inspect(err));

        console.log("parsing form now...");

    });

  // log any errors that occur
  form.on('error', function(err) {
    console.log('An error has occured: \n' + err);
  });

  // once all the files have been uploaded, send a response to the client
  form.on('end', function() {
        console.log('File uploaded to location : ' + form.uploadDir);
    res.end('success');
  });


});

person Curious101    schedule 16.07.2016    source источник


Ответы (1)


Я предполагаю, что form.parse предоставляет эти дополнительные параметры

 form.parse(req, function(err, fields, files) {
   console.log("parsing form now..."+ JSON.stringify(fields));
 });

Если вы все еще хотите раньше, проверьте это

 form.on('field', function(name, value) { }); 

а если это тоже произойдет поздно, попробуйте переупорядочить последовательность из HTML-формы.

person enRaiser    schedule 16.07.2016
comment
form.parse предоставляет доступ к полям, но проблема в том, что по какой-то причине form.parse запускается после завершения загрузки файла. Вот последовательность, в которой эти методы выполняются: получен запрос на загрузку, начало введенного файла, form.on «файл» и затем form.parse. мне нужен доступ к полям, прежде чем я начну загрузку, чтобы я мог аутентифицировать пользователя. - person Curious101; 16.07.2016
comment
Я уже этим занимаюсь, переименование на тот момент работает нормально. Дело в том, что если пользователь не авторизован, то почему загрузка должна проходить и занимать ресурсы сервера. - person Curious101; 16.07.2016
comment
вы пробовали form.on ('field', function (name, value) {}); и в случае, если он также опаздывает, попробуйте переупорядочить последовательность из HTML-формы - person enRaiser; 16.07.2016
comment
Спасибо ! это сработало очень хорошо. form.on ('поле', функция (имя, значение) {}); вызывается перед началом файла. Я приму этот ответ, он делает именно то, что мне нужно. - person Curious101; 16.07.2016