【问题标题】:Dynamically adding files to a input将文件动态添加到输入
【发布时间】:2020-08-14 20:37:25
【问题描述】:

我正在使用这个插件: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
    });
    [...]
});

【问题讨论】:

    标签: javascript php jquery html jquery-html5uploader


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 是的,我知道,但它会动态上传文件(使用namepostUrl 参数),而不是在用户单击提交按钮时。我错了吗?我正在使用 PHP,所以我必须使用全局 $_POST 变量访问文件数据。
      • 让我们说你 postUrl 是 post.php,当图像发布到该 url 时,你将它们的名称和文件夹添加到数据库并返回它的 id(或 ids)......现在在你上传的表单中你需要有 js 函数并监听 onSuccess 事件.. 在这种情况下,您将返回上传图像的 id,而不是通过 javascript/jquery 将该 id 添加到隐藏输入字段.. 提交表单时,您将获得 tham images id
      【解决方案3】:

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

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

      【讨论】:

      • 你能检查我在主信息中的变化吗?
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        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>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-11
          • 2011-02-10
          • 1970-01-01
          • 1970-01-01
          • 2011-06-18
          相关资源
          最近更新 更多