我正在尝试使用blueimp的jQuery File Upload来允许用户上传文件。 按照设置说明,开箱即用。但是为了在我的网站上实际使用它,我希望能够做一些事情:
该插件的所有文件都位于根目录下的文件夹中。
在所有情况下,预览显示,进度条运行,但文件无法上传,我在控制台中收到此错误: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');
});
<小时/> 缺乏文件令我感到惊讶;似乎改变应该是一件简单的事情。如果有人能解释如何做到这一点,我将不胜感激。
答案 0 :(得分:66)
几天前我一直在寻找类似的功能,并且遇到了一个关于tutorialzine的好教程。这是一个有效的例子。完整的教程可以找到here。
用于保存文件上传对话框的简单表单:
<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();
}
上述代码可以添加到任何现有表单中。添加后,该程序会自动上传图像。您可以在提交现有表单时更改此功能并提交图像。
使用实际代码更新了我的答案。所有学分均为原作者。
来源: http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/
答案 1 :(得分:25)
我刚刚花了2个小时与jQuery上传进行斗争,但由于依赖程序的数量而放弃了(我有13个JS文件可以获得所有的花里胡哨)。
我做了一些搜索,遇到了一个名为Dropzone.js的整洁项目,该项目没有任何依赖项。
作者还创建了一个受{jQuery File Upload插件启发的bootstrap demo。
我希望这能节省一些时间。
答案 2 :(得分:4)
我也在努力解决这个问题,但是一旦我弄清楚路径在UploadHandler.php中是如何工作的,它就能让它工作:upload_dir和upload_url是关于让它工作的唯一设置。另请检查服务器错误日志以获取调试信息。
答案 3 :(得分:3)
使用dropper jquery插件查看带有图像预览的图像拖放上传器。
<强> HTML 强>
<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
}
答案 4 :(得分:2)
这是一个很好的Angular插件,用于上传文件,它是免费的!
答案 5 :(得分:1)
我在这个插件上挣扎了一段时间在Rails上,然后有人把它搞砸了我已经创建的所有代码。
虽然看起来你没有在Rails中使用它,但是如果有人使用它,请查看此gem。来源在这里 - &gt; jQueryFileUpload Rails。
更新:
为了满足评论者的需求,我更新了答案。基本上是“use this gem,here is the source code”如果它消失了,那么就这么做了。
答案 6 :(得分:1)
你好试试波纹管链接很容易。我被困了很长时间,它在几分钟内解决了我的问题。 http://simpleupload.michaelcbrook.com/#examples
答案 7 :(得分:1)
Droply.js对此非常适合。它很简单,并且预先打包了一个演示站点,可以直接使用。
答案 8 :(得分:1)
现在是 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">
注册任何其他插件:
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageExifOrientation,
FilePondPluginFileValidateSize,
FilePondPluginImageEdit);
然后在元素中连线:
// 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
上传和转换图像设置非常简单,运行它的人非常擅长支持。
正如你所知道的,我是个粉丝。
答案 9 :(得分:0)
您可以使用uploadify 这是我用过的最好的multiupload jquery插件。
实施简单,浏览器支持完善。
答案 10 :(得分:0)
对于UI插件,使用jsp页面和Spring MVC ..
示例 html 。需要位于形式元素中 id 属性为 fileupload
@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;
}
示例上传和删除请求处理程序
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;
}
}
用于生成所需json响应的示例类
this.page.identifier
请参阅https://pitipata.blogspot.co.ke/2017/01/using-jquery-file-upload-ui.html