Несколько файлов с одинаковым именем не загружаются в петлю - PullRequest
2 голосов
/ 27 марта 2019

Я загружаю файлы, используя URL-адрес REST Loopback3.После отправки формы значения вставляются и файлы сохраняются.Теперь, если я загружаю файл с тем же, который уже выходит, файл не сохраняется. Как переименовать файл с последующим произвольным числом и сохранить.

HTML

<form  id="myForm" novalidate class="formval" >
    <div class="form-row">
       <div class="form-group col-md-6">
          <input type="text" class="form-control" id="firstname" name="firstname" placeholder="First Name" required>
       </div>
       <div class="form-group col-md-6">
          <input type="text" class="form-control" id="lastname" name="lastname" placeholder="Last Name" required>
       </div>
    </div>
    <div class="form-row">
       <div class="form-group col-md-12">
         <textarea class="form-control" id="message" name="message" placeholder="Message"></textarea>
       </div>
    </div>
    <div class="form-row">
       <div class="form-group col-md-8">
          <input type="file"  id="resume" class="form-control" name="resume" accept=".doc,.docx,.pdf" required />
       </div>
    </div>
    <input type="submit" class="btn btn-primary mt-10" id="item-submit" value="submit">
</form>

Сценарий:

  var $firstname, $lastname, $message, $resume, $inserted_date, ins_date;


var apiUrl = 'http://localhost:3000/api/';

$(document).ready(function() {
   var random = Math.random( ); 
    $('#myForm').on('submit', handleForm);
     ins_date=new Date($.now()).toLocaleString();
    $firstname = $('#firstname');
    $lastname = $('#lastname');
    $message = $('#message');
    $resume = $('#resume');
    $inserted_date=ins_date;
});


function handleForm(e) {
    e.preventDefault();

    var career = {
      firstname:$firstname.val(),
      lastname:$lastname.val(),
      message:$message.val(),
      inserted_date:ins_date
    }
    console.log(career);
    $.post(apiUrl + 'careers', career).then(function(res) {
        career = res;
        var promises = [];
        if($resume.val() != '') {
            console.log('i need to process the resume upload');
            promises.push(sendFile($resume.get(0).files[0], apiUrl + 'attachments/resume/upload'));
        }
        Promise.all(promises).then(function(results) {
            console.log('back from all promises', results);
            if(promises.length >= 1) {
                results.forEach(function(resultOb) {
                    if(resultOb.result.files && resultOb.result.files.file[0].container) {
                     career[resultOb.result.files.file[0].container] = resultOb.result.files.file[0].name;
                    }
                });
                console.dir(career);
                var id = career.id;
                delete career.id;
                $.post(apiUrl + 'careers/'+id+'/replace', career).then(function() {
                });
            } else {
            }
        });

    });

}

function sendFile(file, url) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        var fd = new FormData();
        xhr.open("POST", url, true);
        xhr.onreadystatechange = function() {
            if(xhr.readyState == 4 && xhr.status == 200) {
                resolve(JSON.parse(xhr.responseText));
            }
        };
        fd.append('file', file);
        xhr.send(fd);
        $(".alert-success").removeClass("d-none");
          $(".alert-success").fadeTo(2000, 500).slideUp(500, function(){
            $(".alert-success").slideUp(500);
         });
          $('#myForm')[0].reset();
    });
}

Ответы [ 5 ]

2 голосов
/ 27 марта 2019

Похоже, вы используете loopback-component-storage .

Я бы посоветовал просто использовать атрибут nameConflict при создании источника данных, как в следующем примере - поскольку похоже, что вы уже получили загруженное имя файла:

В вашем Loopback'е server / server.js

var ds = loopback.createDataSource({
    connector: require('loopback-component-storage'),
    provider: 'filesystem',
    root: path.join(__dirname, 'attachments'),
    nameConflict: 'makeUnique' // simply add this line!
});

var container = ds.createModel('attachments');
1 голос
/ 27 марта 2019

Вам нужно добавить что-то уникальное в имя файла каждого загруженного файла. Самый простой (вероятно, не самый лучший) способ - добавить текущую метку времени.

Синтаксис для добавления файлов в объект FormData: formData.append(name, value); или formData.append(name, value, filename);. Если вы используете первую версию и пропускаете аргумент filename, по умолчанию используется атрибут name file. MDN

В вашем случае вам не нужно имя файла по умолчанию, вам нужно добавить к нему метку времени.
Вы можете получить текущую метку времени, используя Date.now() или new Date().getTime(). В этом случае лучше использовать Date.now(), потому что он более чем в два раза быстрее (и тоже меньше печатает), чем new Date().getTime().

Таким образом, теперь вы можете создать уникальное имя файла, например:

`${Date.now()}_${file.name}`

Мы ставим время на первое место, потому что file.name содержит расширение файла, и вы этого хотите. Это сгенерирует что-то вроде этого '1553690001341_whatever.jpg'
Но если сначала указать имя файла, вы получите 'whatever.jpg_1553690001341', и поэтому файл не будет сохранен с расширением файла на сервере, и если кто-то загрузит его с сервера, он не будет знать, как его открыть.

Также мы используем обратные тики для использования переменных внутри строки, это просто немного упрощает ситуацию. Если вы не используете обратные метки, вы можете получить тот же результат, используя +, например:

Date.now() + '_' + file.name

Теперь все, что вам нужно сделать, это добавить имя файла при добавлении файла в FormData. Так что пиши

fd.append('file', file, `${Date.now()}_${file.name}`);

вместо

fd.append('file', file);

PS: Подобные вещи должны обрабатываться бэкэнд API

0 голосов
/ 27 марта 2019

Loopback может переименовывать файлы сам при сохранении: https://loopback.io/doc/en/lb3/Storage-component.html#renaming-files

0 голосов
/ 27 марта 2019

Когда я прочитал ваш запрос, я понял, что вы пытаетесь загрузить файл с помощью обратной связи. Даже загрузка с использованием loopback работает нормально, но вы хотите загрузить файл с тем же именем, верно?

Если это так, вы сохраняете файлы, используя управление версиями, добавляя некоторый ключевой текст в конце строки'_v1 ', где вы можете проверить приращение значения при новой загрузке. Или же простым способом будет то, что вы можете объединить временную метку в формате Unix, которая будет серией чисел и будет уникальной для каждой секунды. Таким образом, вы можете сохранить это имя в БД для справки.

например:

var filename = filename +'_'+ new Date().getTime();
0 голосов
/ 27 марта 2019

Попробуйте назвать их по-разному в зависимости от порядка их создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...