0

我正在使用这个插件:jQuery HTML5 上传器(参见演示),在一个表单中。我想在用户提交表单时使用 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
    });
    [...]
});
4

5 回答 5

3

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

于 2014-02-19T14:45:02.053 回答
0

由于浏览器安全性,您不能在文件上传器中选择文件。

用户只能这样做而不是脚本。

于 2014-02-19T14:42:56.300 回答
0

该脚本已经将文件上传到服务器..您需要一种从服务器取回文件名/ID并将它们附加到隐藏表单的方法..而不是当有人提交表单时,您将知道他上传了哪些文件。 .

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

于 2014-02-19T14:48:11.113 回答
0

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

于 2019-03-13T13:52:42.313 回答
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>

于 2020-08-14T12:37:25.077 回答