如何在表单POST请求中单独上传所选文件?

时间:2018-02-05 01:06:19

标签: javascript jquery html

我想要什么

人们点击添加图片按钮,他们选择图片,图片被添加到图库。

他们可以通过点击交叉标志来删除图像,然后重新点击添加图片按钮以添加更多图像。

这一切都有效,我引用了所有File元素。

但是,我无法弄清楚如何在表单的请求后发送文件。

问题问题在于您无法创建FileList输出文件数组,或将文件数组设置为input.files = arrOfFiles

输入元素本身不允许您添加更多文件或删除文件...它只是用新文件替换旧文件。

这不是我想要的,因此我将继续引用js中的文件对象,并让用户删除图像或添加更多图像。

我知道我可以将单个文件作为XHR发送,但我想通过已存在的表单发送它们。

我想知道一种通过表格而不是js发送文件的方法,但显然不可能

2 个答案:

答案 0 :(得分:2)

这正是FormData API的用途:从头开始创建一个表单数据,您可以将其上传到服务器,就好像它是从<form>对象创建的,除了您可以控制是什么在那里。

因此,要在FormData中附加文件或Blob,代码为

var fd = new FormData();
fd.append(field_name, blob, file_name);

要附加多个文件,您可以再次调用fd.append,但请注意,后端通常需要格式化field_name,以便他们可以在此处了解多个值。 通常,这是通过在您的字段名后添加[]来完成的。

var fd = new FormData();
fd.append('files[]', blob_1, file_name_1);
fd.append('files[]', blob_2, file_name_2);

然后你可以通过AJAX请求将它发送到你的服务器,这不会对这个请求和单个<input multiple name="files[]">的真实请求产生影响。

请注意,对于File, file_name 是可选的,如果未设置,则默认为文件名。但是,如果您不想设置随机名称,则需要Blob。

var file_1 = new File(['foo'], 'file1.txt',{type:'text/plain'});
var file_2 = new File(['bar'], 'file2.txt', {type:'text/plain'});

var fd = new FormData();
fd.append('files[]', file_1);
fd.append('files[]', file_2);

console.log(...fd.entries());

// and to send it to your server
var xhr = new XMLHttpRequest();
xhr.open('POST', 'your_server_url');
xhr.send(fd);

答案 1 :(得分:-1)

如果您要上传图片。考虑使用base64编码。这就是我做的。将base64编码的URL分配给stringify JSON,或任何你想要的更容易的东西。

当数据被POST时,在那里进行转换,以获取文件以保存它们。解码base64将取决于您的后端语言,但您在问题中未提及。

在JavaScript中,您可以使用此功能以预览状态加载图像,如上所述。

 function previewImage (inputId, eleId) {
        if (window.FileReader) {
                var oPreviewImg = null, oFReader = new window.FileReader(),
                        rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;

                oFReader.onload = function (oFREvent) {
                    if (!oPreviewImg) {
                        var newPreview = document.getElementById(eleId);
                        oPreviewImg = new Image();
                        oPreviewImg.style.width = (newPreview.offsetWidth).toString() + "px";
                        oPreviewImg.style.height = (newPreview.offsetHeight).toString() + "px";
                        if(newPreview.children.length > 0)
                            newPreview.replaceChild(oPreviewImg, newPreview.children[0]);
                        else
                            newPreview.appendChild(oPreviewImg);
                    }
                    oPreviewImg.src = oFREvent.target.result;
                    // Add Bootstrap's img-thumbnail class to the image frame
                    oPreviewImg.classList.add("img-thumbnail");
                };

                return function () {
                    var aFiles = document.getElementById(inputId).files;
                    if (aFiles.length === 0) { return; }
                    if (!rFilter.test(aFiles[0].type)) { alert("You must select a valid image file!"); return; }
                    oFReader.readAsDataURL(aFiles[0]);
                }


        }
        if (navigator.appName === "Microsoft Internet Explorer") {
            return function () {
                document.getElementById(eleId).filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = document.getElementById(inputId).value;
            }
        }


    };

然后,您可以从src元素的img属性中提取base64网址。

您可以通过破坏img元素来推出自己首选的“取消”上传内容的方法。