有人能解释一下如何实现 jQuery 文件上传插件吗?

编辑(2019年10月) :

6年过去了,jQuery 文件上传显然还在让人抓狂。如果你在这里的答案中找不到什么安慰的话,可以尝试一个现代的 搜索 NPM替代品。不值得这么麻烦,我保证。

我在之前的编辑中推荐了 Uploadify,但是,正如一位评论者指出的那样,他们似乎不再提供免费版本了。反正上传是2013年的 所以


编辑:

这似乎仍然得到流量,所以我将解释我最终做了什么。我最终得到了工作的插件按照教程在接受的答案。然而,jQuery 文件上传是一个真正的麻烦,如果你正在寻找一个更简单的文件上传插件,我强烈推荐[ Uploadify ]( http://www.Uploadify.com )。正如一个答案所指出的那样,它只对非商业用途免费。

背景资料

我正在尝试使用蓝精灵的 jQuery File Upload来允许用户上传文件。开箱即用,效果完美,按照设置说明进行操作。但是要在我的网站上实际使用它,我希望能够做到以下几点:

  • 包括我现有的任何网页上的上传
  • 更改上载文件的目录

插件的所有文件都位于根目录下的一个文件夹中。

我试过了。

  • 将演示页面移动到根目录并更新必要脚本的路径
  • 按照建议的 给你更改 UploadHandler.php 文件中的“ uploaddir”和“ uploadurl”选项。
  • 在演示 javascript 的第二行中更改 URL

在所有情况下,都会显示预览,并运行进度条,但是文件无法上传,我在控制台中得到了这个错误: Uncaught TypeError: Cannot read property 'files' of undefined。我不明白插件的所有部分是如何工作的,这使得它很难调试。

密码

演示页面中的 javascript:

$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = 'file_upload/server/php/UploadHandler.php',
uploadButton = $('<button/>')
.addClass('btn')
.prop('disabled', true)
.text('Processing...')
.on('click', function () {
var $this = $(this),
data = $this.data();
$this
.off('click')
.text('Abort')
.on('click', function () {
$this.remove();
data.abort();
});
data.submit().always(function () {
$this.remove();
});
});
$('#fileupload').fileupload({
url: url,
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000, // 5 MB
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
previewMaxWidth: 100,
previewMaxHeight: 100,
previewCrop: true
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node
.prepend('<br>')
.prepend(file.preview);
}
if (file.error) {
node
.append('<br>')
.append(file.error);
}
if (index + 1 === data.files.length) {
data.context.find('button')
.text('Upload')
.prop('disabled', !!data.files.error);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}).on('fileuploaddone', function (e, data) {
$.each(data.result.files, function (index, file) {
var link = $('<a>')
.attr('target', '_blank')
.prop('href', file.url);
$(data.context.children()[index])
.wrap(link);
});
}).on('fileuploadfail', function (e, data) {
$.each(data.result.files, function (index, file) {
var error = $('<span/>').text(file.error);
$(data.context.children()[index])
.append('<br>')
.append(error);
});
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});

I'm surprised by the lack of documentation; it seems like it should be a simple thing to change. I would appreciate if someone could explain how to do this.
226496 次浏览

你可以使用“ uploadify.com/document/uploadify/實施-uploadify/”rel = “ nofollow”> uploadify 这是我用过的最好的多上传 jquery 插件。

实现简单,浏览器支持完善。

我也曾为此挣扎过,但是在弄清楚 UploadHandler.php 中的路径是如何工作的之后,我就让它工作了: uploadHandler.php: uploaddir 和 uploadurl 是唯一可以让它工作的设置。还要检查服务器错误日志中的调试信息。

几天前我正在寻找一个类似的功能,偶然发现了一个很好的教程。这里有一个实际的例子。完整的教程可以找到 给你

保存文件上传对话的简单表单:

<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="uploadctl" multiple />
<ul id="fileList">
<!-- The file list will be shown here -->
</ul>
</form>

下面是上传文件的 jQuery 代码:

$('#upload').fileupload({


// This function is called when a file is added to the queue
add: function (e, data) {
//This area will contain file list and progress information.
var tpl = $('<li class="working">'+
'<input type="text" value="0" data-width="48" data-height="48" data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" />'+
'<p></p><span></span></li>' );


// Append the file name and file size
tpl.find('p').text(data.files[0].name)
.append('<i>' + formatFileSize(data.files[0].size) + '</i>');


// Add the HTML to the UL element
data.context = tpl.appendTo(ul);


// Initialize the knob plugin. This part can be ignored, if you are showing progress in some other way.
tpl.find('input').knob();


// Listen for clicks on the cancel icon
tpl.find('span').click(function(){
if(tpl.hasClass('working')){
jqXHR.abort();
}
tpl.fadeOut(function(){
tpl.remove();
});
});


// Automatically upload the file once it is added to the queue
var jqXHR = data.submit();
},
progress: function(e, data){


// Calculate the completion percentage of the upload
var progress = parseInt(data.loaded / data.total * 100, 10);


// Update the hidden input field and trigger a change
// so that the jQuery knob plugin knows to update the dial
data.context.find('input').val(progress).change();


if(progress == 100){
data.context.removeClass('working');
}
}
});
//Helper function for calculation of progress
function formatFileSize(bytes) {
if (typeof bytes !== 'number') {
return '';
}


if (bytes >= 1000000000) {
return (bytes / 1000000000).toFixed(2) + ' GB';
}


if (bytes >= 1000000) {
return (bytes / 1000000).toFixed(2) + ' MB';
}
return (bytes / 1000).toFixed(2) + ' KB';
}

下面是处理数据的 PHP 代码示例:

if($_POST) {
$allowed = array('jpg', 'jpeg');


if(isset($_FILES['uploadctl']) && $_FILES['uploadctl']['error'] == 0){


$extension = pathinfo($_FILES['uploadctl']['name'], PATHINFO_EXTENSION);


if(!in_array(strtolower($extension), $allowed)){
echo '{"status":"error"}';
exit;
}


if(move_uploaded_file($_FILES['uploadctl']['tmp_name'], "/yourpath/." . $extension)){
echo '{"status":"success"}';
exit;
}
echo '{"status":"error"}';
}
exit();
}

The above code can be added to any existing form. This program automatically uploads images, once they are added. This functionality can be changed and you can submit the image, while you are submitting your existing form.

用实际代码更新了我的答案。所有的学分归于代码的原作者。

来源: Http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/

我曾经在 Rails 上和这个插件斗争过一段时间,然后有人把它合并了,取代了我所创建的所有代码。

Although it looks like you're not using this in Rails, however if anyone is using it checkout this gem. The source is here --> JQueryFileUpload Rails.

更新:

为了满足评论者,我更新了我的答案。本质上是“ 用这颗宝石这是源代码”如果它消失了,那么做它的漫长的道路。

我刚刚花了2个小时与 jQuery Upload 作斗争,但是由于依赖关系的数量而放弃了(我有13个 JS 文件来获得所有的附加功能)。

我做了更多的搜索,发现了一个叫做 Dropzone.js的整洁的项目,它没有任何依赖关系。

作者还创建了一个受 jQuery 文件上传插件启发的 引导程序演示

我希望这能节省别人的时间。

Check out the Image drag and drop uploader with image preview using dropper jquery plugin.

超文本标示语言

<div class="target" width="78" height="100"><img /></div>

JS

$(".target").dropper({
action: "upload.php",


}).on("start.dropper", onStart);
function onStart(e, files){
console.log(files[0]);


image_preview(files[0].file).then(function(res){
$('.dropper-dropzone').empty();
//$('.dropper-dropzone').css("background-image",res.data);
$('#imgPreview').remove();
$('.dropper-dropzone').append('<img id="imgPreview"/><span style="display:none">Drag and drop files or click to select</span>');
var widthImg=$('.dropper-dropzone').attr('width');
$('#imgPreview').attr({width:widthImg});
$('#imgPreview').attr({src:res.data});


})


}


function image_preview(file){
var def = new $.Deferred();
var imgURL = '';
if (file.type.match('image.*')) {
//create object url support
var URL = window.URL || window.webkitURL;
if (URL !== undefined) {
imgURL = URL.createObjectURL(file);
URL.revokeObjectURL(file);
def.resolve({status: 200, message: 'OK', data:imgURL, error: {}});
}
//file reader support
else if(window.File && window.FileReader)
{
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function () {
imgURL = reader.result;
def.resolve({status: 200, message: 'OK', data:imgURL, error: {}});
}
}
else {
def.reject({status: 1001, message: 'File uploader not supported', data:imgURL, error: {}});
}
}
else
def.reject({status: 1002, message: 'File type not supported', error: {}});
return def.promise();
}


$('.dropper-dropzone').mouseenter(function() {
$( '.dropper-dropzone>span' ).css("display", "block");
});


$('.dropper-dropzone').mouseleave(function() {
$( '.dropper-dropzone>span' ).css("display", "none");
});

CSS

.dropper-dropzone{
width:78px;
padding:3px;
height:100px;
position: relative;
}
.dropper-dropzone>img{
width:78px;
height:100px;
margin-top=0;
}


.dropper-dropzone>span {
position: absolute;
right: 10px;
top: 20px;
color:#ccc;




}


.dropper .dropper-dropzone{


padding:3px !important
}

演示 Jsfiddle

This is good Angular plugin for uploading files, and its free!

角度文件上传

对于 UI 插件,使用 jsp page 和 Spring MVC. 。

样本 Html。需要在 form元素内,id属性为 文件上传

    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
<div class="fileupload-buttonbar">
<div>
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files</span>
<input id="fileuploadInput" type="file" name="files[]" multiple>
</span>
<%-- https://stackoverflow.com/questions/925334/how-is-the-default-submit-button-on-an-html-form-determined --%>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
<!-- The global file processing state -->
<span class="fileupload-process"></span>
</div>
<!-- The global progress state -->
<div class="fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended">&nbsp;</div>
</div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>


<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/css/jquery.fileupload.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/css/jquery.fileupload-ui.css">


<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-process.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-validate.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-ui.js"></script>


<script type="text/javascript">
$(document).ready(function () {
var maxFileSizeBytes = ${maxFileSizeBytes};
if (maxFileSizeBytes < 0) {
//-1 or any negative value means no size limit
//set to undefined
//https://stackoverflow.com/questions/5795936/how-to-set-a-javascript-var-as-undefined
maxFileSizeBytes = void 0;
}


//https://github.com/blueimp/jQuery-File-Upload/wiki/Options
//https://stackoverflow.com/questions/34063348/jquery-file-upload-basic-plus-ui-and-i18n
//https://stackoverflow.com/questions/11337897/how-to-customize-upload-download-template-of-blueimp-jquery-file-upload
$('#fileupload').fileupload({
url: '${pageContext.request.contextPath}/app/uploadResources.do',
fileInput: $('#fileuploadInput'),
acceptFileTypes: /(\.|\/)(jrxml|png|jpe?g)$/i,
maxFileSize: maxFileSizeBytes,
messages: {
acceptFileTypes: '${fileTypeNotAllowedText}',
maxFileSize: '${fileTooLargeMBText}'
},
filesContainer: $('.files'),
uploadTemplateId: null,
downloadTemplateId: null,
uploadTemplate: function (o) {
var rows = $();
$.each(o.files, function (index, file) {
var row = $('<tr class="template-upload fade">' +
'<td><p class="name"></p>' +
'<strong class="error text-danger"></strong>' +
'</td>' +
'<td><p class="size"></p>' +
'<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
'<div class="progress-bar progress-bar-success" style="width:0%;"></div></div>' +
'</td>' +
'<td>' +
(!index && !o.options.autoUpload ?
'<button class="btn btn-primary start" disabled>' +
'<i class="glyphicon glyphicon-upload"></i> ' +
'<span>${startText}</span>' +
'</button>' : '') +
(!index ? '<button class="btn btn-warning cancel">' +
'<i class="glyphicon glyphicon-ban-circle"></i> ' +
'<span>${cancelText}</span>' +
'</button>' : '') +
'</td>' +
'</tr>');
row.find('.name').text(file.name);
row.find('.size').text(o.formatFileSize(file.size));
if (file.error) {
row.find('.error').text(file.error);
}
rows = rows.add(row);
});
return rows;
},
downloadTemplate: function (o) {
var rows = $();
$.each(o.files, function (index, file) {
var row = $('<tr class="template-download fade">' +
'<td><p class="name"></p>' +
(file.error ? '<strong class="error text-danger"></strong>' : '') +
'</td>' +
'<td><span class="size"></span></td>' +
'<td>' +
(file.deleteUrl ? '<button class="btn btn-danger delete">' +
'<i class="glyphicon glyphicon-trash"></i> ' +
'<span>${deleteText}</span>' +
'</button>' : '') +
'<button class="btn btn-warning cancel">' +
'<i class="glyphicon glyphicon-ban-circle"></i> ' +
'<span>${clearText}</span>' +
'</button>' +
'</td>' +
'</tr>');
row.find('.name').text(file.name);
row.find('.size').text(o.formatFileSize(file.size));
if (file.error) {
row.find('.error').text(file.error);
}
if (file.deleteUrl) {
row.find('button.delete')
.attr('data-type', file.deleteType)
.attr('data-url', file.deleteUrl);
}
rows = rows.add(row);
});
return rows;
}
});


});
</script>

上传和删除请求处理程序示例

    @PostMapping("/app/uploadResources")
public @ResponseBody
Map<String, List<FileUploadResponse>> uploadResources(MultipartHttpServletRequest request,
Locale locale) {
//https://github.com/jdmr/fileUpload/blob/master/src/main/java/org/davidmendoza/fileUpload/web/ImageController.java
//https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler
Map<String, List<FileUploadResponse>> response = new HashMap<>();
List<FileUploadResponse> fileList = new ArrayList<>();


String deleteUrlBase = request.getContextPath() + "/app/deleteResources.do?filename=";


//http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/MultipartRequest.html
Iterator<String> itr = request.getFileNames();
while (itr.hasNext()) {
String htmlParamName = itr.next();
MultipartFile file = request.getFile(htmlParamName);
FileUploadResponse fileDetails = new FileUploadResponse();
String filename = file.getOriginalFilename();
fileDetails.setName(filename);
fileDetails.setSize(file.getSize());
try {
String message = saveFile(file);
if (message != null) {
String errorMessage = messageSource.getMessage(message, null, locale);
fileDetails.setError(errorMessage);
} else {
//save successful
String encodedFilename = URLEncoder.encode(filename, "UTF-8");
String deleteUrl = deleteUrlBase + encodedFilename;
fileDetails.setDeleteUrl(deleteUrl);
}
} catch (IOException ex) {
logger.error("Error", ex);
fileDetails.setError(ex.getMessage());
}


fileList.add(fileDetails);
}


response.put("files", fileList);


return response;
}


@PostMapping("/app/deleteResources")
public @ResponseBody
Map<String, List<Map<String, Boolean>>> deleteResources(@RequestParam("filename") List<String> filenames) {
Map<String, List<Map<String, Boolean>>> response = new HashMap<>();
List<Map<String, Boolean>> fileList = new ArrayList<>();


String templatesPath = Config.getTemplatesPath();
for (String filename : filenames) {
Map<String, Boolean> fileDetails = new HashMap<>();


String cleanFilename = ArtUtils.cleanFileName(filename);
String filePath = templatesPath + cleanFilename;


File file = new File(filePath);
boolean deleted = file.delete();


if (deleted) {
fileDetails.put(cleanFilename, true);
} else {
fileDetails.put(cleanFilename, false);
}


fileList.add(fileDetails);
}


response.put("files", fileList);


return response;
}

生成所需 json 响应的示例类

    public class FileUploadResponse {
//https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler


private String name;
private long size;
private String error;
private String deleteType = "POST";
private String deleteUrl;


/**
* @return the name
*/
public String getName() {
return name;
}


/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}


/**
* @return the size
*/
public long getSize() {
return size;
}


/**
* @param size the size to set
*/
public void setSize(long size) {
this.size = size;
}


/**
* @return the error
*/
public String getError() {
return error;
}


/**
* @param error the error to set
*/
public void setError(String error) {
this.error = error;
}


/**
* @return the deleteType
*/
public String getDeleteType() {
return deleteType;
}


/**
* @param deleteType the deleteType to set
*/
public void setDeleteType(String deleteType) {
this.deleteType = deleteType;
}


/**
* @return the deleteUrl
*/
public String getDeleteUrl() {
return deleteUrl;
}


/**
* @param deleteUrl the deleteUrl to set
*/
public void setDeleteUrl(String deleteUrl) {
this.deleteUrl = deleteUrl;
}


}

参见 https://pitipata.blogspot.co.ke/2017/01/using-jquery-file-upload-ui.html

嗨,试试下面的链接,很简单。我被困在这里很长时间了,它在几分钟内就解决了我的问题。 Http://simpleupload.michaelcbrook.com/#examples

Js 非常适合这个,它很简单,并且预装了一个开箱即用的演示站点。

现在是2021年,这里有一个非常简单的插件可以上传任何东西:

Https://pqina.nl/filepond/?ref=pqina

加入你的元素:

<input type="file"
class="filepond"
name="filepond"
multiple
data-allow-reorder="true"
data-max-file-size="3MB"
data-max-files="3">

Register any additional plugins:

  FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageExifOrientation,
FilePondPluginFileValidateSize,
FilePondPluginImageEdit);

Then wire in the element:

// Select the file input and use
// create() to turn it into a pond
FilePond.create(
document.querySelector('input'),


// Use Doka.js as image editor
imageEditEditor: Doka.create({
utils: ['crop', 'filter', 'color']
})
);

我使用这个附加的 Doka 图像编辑器在 https://www.yoodu.co.uk上传和转换图像

crazy simple to setup and the guys who run it are great at support.

你也看得出来,我是你的粉丝。