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

问题描述 投票:2回答:5

我使用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();
    });
}
javascript jquery file-upload loopbackjs file-rename
5个回答
2
投票

看起来你正在使用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
投票

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

将文件附加到FormData对象的语法是:formData.append(name, value);formData.append(name, value, filename);。如果您使用第一个版本并跳过filename参数,则默认为namefile属性。 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
投票

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


0
投票

正如我已阅读您的请求,我了解您正在尝试使用环回上传文件。即使使用loopback上传工作正常,但您的请求是上传同名文件吗?

如果是,则通过在结束行'_v1'处添加一些关键文本来使用版本控制存储文件,您可以在其中检查新上载的值的增量。或者,一个简单的方法是你可以用Unix格式连接时间戳,这将是一系列数字,并且每秒都是唯一的。因此,您可以将此名称保存在DB中供您参考。

例如:

var filename = filename +'_'+ new Date().getTime();

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.