动态添加文件到输入

时间:2014-02-19 14:41:32

标签: javascript php jquery html5 jquery-html5uploader

我在表单中使用此插件:jQuery HTML5 uploader(请参阅演示)。我想在用户提交表单时使用POST方法发送上传的文件。

也许我可以创建input[type="file"],隐藏它,并在输入中使用插件动态添加上传的文件?有可能吗?


所以,如果我不能这样做,只有当用户点击提交按钮时,如何使用此插件将文件上传到服务器?我知道这个插件已经用AJAX做了,但我想上传它们只有如果用户点击按钮。

也许我应该创建一个名为files的变量,当用户点击提交按钮时,我自己使用AJAX发送文件和其他输入数据?

这样的事情:

jQuery( "#dropbox" ).html5Uploader({
    onClientLoadStart: function( event, file ) {
        files[] = file;
        [...]
    }
});

[...]

jQuery("#button").on("click", function() {
    jQuery.ajax({
        data: files
    });
    [...]
});

5 个答案:

答案 0 :(得分:1)

出于安全考虑,你不能这样做。想象一下可能性。我在隐藏字段中通过JavaScript输入文件。你按提交。我收到你的档案。任何文件。可怕,对吧?

答案 1 :(得分:0)

  

由于浏览器的安全性,您无法在文件上传器中选择文件。

用户只能执行此操作而不是脚本。

答案 2 :(得分:0)

这个脚本已经将文件上传到服务器了..你需要的是一种从服务器上取回文件名/ id并将它们附加到隐藏表单的方法..比有人提交表单你会知道哪些文件他上传了..

你可以通过听取onSuccess事件来做到这一点..

答案 3 :(得分:0)

出于安全原因,您不能动态更改type文件输入字段的值。如果可能的话,恶意用户可以将值设置为:“ c:\ maliciousfile”并损害您的系统

答案 4 :(得分:0)

看起来您的问题分为两部分:

  1. 如何使用JavaScript将文件动态添加到表单中

    1a。 (我会提供奖金-预览图像)

  2. 如何执行Ajax文件上传

1将文件动态添加到表单

您要在此处创建一个<input type="file">字段并通过Javascript更改表单值。您可以使用CSS display: none;隐藏输入。

据我所知,这只能通过FileReader API拖放来完成,并且API受到限制。

您可以替换和删除输入中的所有文件,但不能添加或删除单个文件。

基本的拖放文件上传如下:

const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');

dropzone.addEventListener('dragover', event => {
  // we must preventDefault() to let the drop event fire
  event.preventDefault();
});
dropzone.addEventListener('drop', event => {
  event.preventDefault();
  // drag/drop files are in event.dataTransfer
  let files = event.dataTransfer.files;
  fileInput.files = files;
  console.log(`added ${files.length} files`);
});
.upload {
  border: 1px solid #eee;
  border-radius:  10px;
  padding: 20px
}

.hidden {
  opacity: 0.5; 
}
<div id="dropzone" class="upload">Drop images here</div>
<input type="file" id="file-input" class="hidden" />

1a预览文件

使用Javascript打开了一些有趣的表单交互选项,例如预览上传的文件。以一个可以上载多个拖放图像的图像上传器为例。

const imageTypeFilter = /image.*/;

const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');
const previewContainer = document.getElementById('preview-container');

function generateImagePreview(file) {
    const fileReader = new FileReader();
    fileReader.addEventListener('load', event => {
      // generate an image preview
      let image = document.createElement('img');
      image.classList.add('preview-image');
      srcAttr = document.createAttribute('src');
      srcAttr.value = fileReader.result;
      image.setAttributeNode(srcAttr);
      previewContainer.append(image);
    }, false); 
    // open and read the file
    fileReader.readAsDataURL(file);
}

function processFiles(files) {
  previewContainer.innerHTML = "";
  ([...files]).forEach((file, index) => {
    if (!file.type.match(imageTypeFilter)) {
      console.error("Incorrect file type:");
      console.log(file);
    } else {
      generateImagePreview(file);
    }
  });
}

dropZone.addEventListener('dragover', event => {
  // required to fire the drop event
  event.preventDefault();
});
dropZone.addEventListener('drop', event => {
  event.preventDefault();
  const files = event.dataTransfer.files;
  fileInput.files = files;
  processFiles(files);
});

fileInput.addEventListener('change', event => {
  processFiles(event.target.files);
});
.upload {
  border: 1px solid #eee;
  border-radius:  10px;
  padding: 20px
}

.preview-image {
  max-width: 100px;
  max-height: 100px;  
}

.hidden {
  opacity: 0.5; 
}
<div id="dropzone" class="upload">
Drag images here
</div>
<input id="file-input" type="file" multiple accept="image/jpeg,image/png,image/gif" class="hidden" />
<div id="preview-container"></div>

2当用户单击提交按钮时执行AJAX上传。

在这种情况下,您想覆盖默认的表单提交事件,我相信它将看起来像这样:

const submitUrl = 'https://httpbin.org/post';
const form = document.getElementById('ajax-form');

form.addEventListener('submit', event => {
  // this line prevents the default submit
  event.preventDefault();
  // convert the form into POST data
  const serializedFormData = new FormData(event.target);
  
  // use your favorite AJAX library
  axios.post(
    submitUrl,
    serializedFormData
  ).then(response => {
    console.log("success!");
  }).catch(error => {
    console.log("falied");
    console.log(error.response);
  });
});
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<form id="ajax-form" method="post" enctype="multipart/form-data">
    <input type="text" name="name"/>
    <input name="file" type="file" />
    <button type="submit">Submit</button>
</form>