选择不在提交表单上的文件上传图片,

时间:2014-01-07 21:21:39

标签: javascript php jquery html forms

我有一个HTML表单,用户可以在输入字段中上传图像,但工作正常但图像在提交表单时上传。

当选择文件并且用户仍在填写表单时,我是否可以将图像上传到TMP目录,然后当用户提交表单时,可以将其移动到实际文件目录。这样可以提供更好的用户体验,特别是互联网连接速度慢的人可以从中受益,因为它可以有效地利用用户的时间。

我不确定,但我认为这需要某种jQuery / Ajax解决方案来上传图像中间表单然后使用PHP将文件从TMP传输到实际目录。

1 个答案:

答案 0 :(得分:1)

正如Diodeus建议的那样,将表单放在iframe中会阻止它在当前页面框架中发布,并允许用户处理其他表单项。更符合您期望的解决方案是使用AJAX请求。您可以查看HTML5 API,有许多不同的已构建解决方案和许多教程。

以下是从this demo at html5demos.com

中提取的一个简单示例
<title>Drag and drop, automatic upload</title>
<style>
#holder { border: 10px dashed #ccc; width: 300px; min-height: 300px; margin: 20px auto;}
#holder.hover { border: 10px dashed #0c0; }
#holder img { display: block; margin: 10px auto; }
#holder p { margin: 10px; font-size: 14px; }
progress { width: 100%; }
progress:after { content: '%'; }
.fail { background: #c00; padding: 2px; color: #fff; }
.hidden { display: none !important;}
</style>
<article>
    <div id="holder">
    </div> 
    <p id="upload" class="hidden"><label>Drag &amp; drop not supported, but you can still upload via this input field:<br><input type="file"></label></p>
    <p id="filereader">File API &amp; FileReader API not supported</p>
    <p id="formdata">XHR2's FormData is not supported</p>
    <p id="progress">XHR2's upload progress isn't supported</p>
    <p>Upload progress: <progress id="uploadprogress" min="0" max="100" value="0">0</progress></p>
    <p>Drag an image from your desktop on to the drop zone above to see the browser both render the preview, but also upload automatically to this server.</p>
</article>
<script>
var holder = document.getElementById('holder'),
        tests = {
            filereader: typeof FileReader != 'undefined',
            dnd: 'draggable' in document.createElement('span'),
            formdata: !!window.FormData,
            progress: "upload" in new XMLHttpRequest
        }, 
        support = {
            filereader: document.getElementById('filereader'),
            formdata: document.getElementById('formdata'),
            progress: document.getElementById('progress')
        },
        acceptedTypes = {
            'image/png': true,
            'image/jpeg': true,
            'image/gif': true
        },
        progress = document.getElementById('uploadprogress'),
        fileupload = document.getElementById('upload');

"filereader formdata progress".split(' ').forEach(function (api) {
    if (tests[api] === false) {
        support[api].className = 'fail';
    } else {
        // FFS. I could have done el.hidden = true, but IE doesn't support
        // hidden, so I tried to create a polyfill that would extend the
        // Element.prototype, but then IE10 doesn't even give me access
        // to the Element object. Brilliant.
        support[api].className = 'hidden';
    }
});

function previewfile(file) {
    if (tests.filereader === true && acceptedTypes[file.type] === true) {
        var reader = new FileReader();
        reader.onload = function (event) {
            var image = new Image();
            image.src = event.target.result;
            image.width = 250; // a fake resize
            holder.appendChild(image);
        };

        reader.readAsDataURL(file);
    }    else {
        holder.innerHTML += '<p>Uploaded ' + file.name + ' ' + (file.size ? (file.size/1024|0) + 'K' : '');
        console.log(file);
    }
}

function readfiles(files) {
        debugger;
        var formData = tests.formdata ? new FormData() : null;
        for (var i = 0; i < files.length; i++) {
            if (tests.formdata) formData.append('file', files[i]);
            previewfile(files[i]);
        }

        // now post a new XHR request
        if (tests.formdata) {
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/devnull.php');
            xhr.onload = function() {
                progress.value = progress.innerHTML = 100;
            };

            if (tests.progress) {
                xhr.upload.onprogress = function (event) {
                    if (event.lengthComputable) {
                        var complete = (event.loaded / event.total * 100 | 0);
                        progress.value = progress.innerHTML = complete;
                    }
                }
            }

            xhr.send(formData);
        }
}

if (tests.dnd) { 
    holder.ondragover = function () { this.className = 'hover'; return false; };
    holder.ondragend = function () { this.className = ''; return false; };
    holder.ondrop = function (e) {
        this.className = '';
        e.preventDefault();
        readfiles(e.dataTransfer.files);
    }
} else {
    fileupload.className = 'hidden';
    fileupload.querySelector('input').onchange = function () {
        readfiles(this.files);
    };
}

</script>

这会创建一个区域来删除文件(而不是浏览按钮),并在发生拖放事件时启动文件上传。它将异步执行,并允许页面内容正常交互,同时传输在后台进行。然而,在这个例子中有一个重要的事情要改变。这一行:

xhr.open('POST', '/devnull.php');

应更改为环境/服务器中的代码文件,该代码文件将处理文件上载数据并保存或处理您需要的文件。该脚本仅作为该脚本的前端。要记住的另一件事是HTML5 File API is still a modern-browser-only type of thing; it's well supported in current browsers, but older ones are out of luck。如果您需要支持它们,您应该寻找另一种解决方案。