具有相同名称的多个文件不会在环回中上传

时间:2019-03-27 11:01:19

标签: javascript jquery file-upload loopbackjs file-rename

我正在使用REST API URL 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 个答案:

答案 0 :(得分:2)

您似乎正在使用loopback-component-storage

我建议在创建数据源时仅使用nameConflict属性,如以下示例所示-因为看起来您已经检索了已上传的文件名:

在环回的 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 :(得分:1)

您需要为每个上传的文件添加唯一的文件名。最简单(可能不是最好)的方法是添加当前时间戳。

将文件追加到FormData对象的语法为:selfformData.append(name, value);。如果您使用第一个版本并跳过formData.append(name, value, filename);参数,则默认为filename的{​​{1}}属性。 MDN

如果您不想使用默认文件名,则需要为其添加时间戳。
您可以使用namefile获取当前时间戳。在这种情况下,最好使用Date.now(),因为它比new Date().getTime()快两倍以上(并且键入的次数也更少)。

因此,您现在可以生成一个像这样的唯一文件名:

Date.now()

我们把时间放在第一位,因为new Date().getTime()包含文件扩展名,而您希望这样做。 这将生成类似`${Date.now()}_${file.name}`
的内容 但是,如果首先输入文件名,您将得到file.name,因此该文件将不会以文件扩展名保存在服务器上,并且如果有人从服务器下载文件,他们将不知道如何打开它。

我们也使用反引号在字符串内使用变量,这只会使事情变得容易一些。如果您不使用反引号,则可以使用'1553690001341_whatever.jpg'获得相同的结果,

'whatever.jpg_1553690001341'

现在您要做的就是在将文件追加到FormData时也添加文件名。所以写

+

代替

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

PS:这些事情应该由后端API处理

答案 2 :(得分:0)

尝试根据创建顺序对它们进行不同的命名。

答案 3 :(得分:0)

在阅读您的请求后,我了解到您正在尝试使用环回上传文件。甚至使用环回进行的上传都可以正常工作,但是您的要求是上传具有相同名称的文件吗?

如果是,则通过在末尾的“ _v1”行添加一些关键文本来使用版本控制存储文件,您可以在其中检查新上载时值的增量。否则,一种简单的方法是您可以将Unix格式的时间戳记串联起来,该时间戳记是一系列数字,并且每秒都是唯一的。因此,您可以将此名称保存在数据库中以供参考。

例如:

redirect_uri

答案 4 :(得分:0)

Loopback在保存时可以重命名文件本身: https://loopback.io/doc/en/lb3/Storage-component.html#renaming-files