我已经对这个错误进行了两个多星期的故障排除,但找不到问题所在。我已经使用 FineUploader 上传多个文件的页面。我有一个项目集合,每个项目都需要获取它自己的图像。所以我在请求中传递一个参数,以识别图像对应的项目。我还有一个图片库和徽标的上传器。
我手动触发上传并在服务器上获取请求,然后设置 req.on(data, function() { ... }) 上传文件。这永远不会被触发。
这是我的代码:
$(document).ready(function () {
window.onSubmit = function (uploaderName) {
return function (id, fileName) {
console.log("Setting parameters...")
window[uploaderName].setParams({
farm: $('input[name=farm-name]').val()
});
}
};
window.logoUploader = new qq.FineUploader({
element: $('#logo')[0],
request: {
endpoint: '/upload/farm/logo'
},
autoUpload: false,
debug: true,
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],
sizeLimit: 1024000 // 50 kB = 50 * 1024 bytes
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Select Logo'
},
callbacks: {
onSubmit: onSubmit("logoUploader")
}
});
window.shareLogoUploader = [];
window.shareLogoUploader[0] = new qq.FineUploader({
element: $('#share-logo-0')[0],
request: {
endpoint: '/upload/farm/share/gallery'
},
autoUpload: false,
debug: true,
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],
sizeLimit: 1024000 // 50 kB = 50 * 1024 bytes
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Select Logo'
}
});
window.galleryUploader = new qq.FineUploader({
element: $('#gallery')[0],
request: {
endpoint: '/upload/farm/gallery/photo'
},
autoUpload: false,
debug: true,
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],
sizeLimit: 2024000 // around 2mbs
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Pics'
},
callbacks: {
onComplete: function (event, id, fileName, responseJSON) {
if (responseJSON.success) {
console.log(responseJSON, fileName);
$('#thumbnails').append('<img src="/uploads/' + fileName + '" width="256px"><input type="hidden" name="photos[]" value="' + fileName + '">');
}
},
onSubmit: onSubmit("galleryUploader")
}
});
});
// Shares
var shares = [];
var sharesGallery = [];
$(function () {
$('section#shares button#add-share').click(function (e) {
e.preventDefault();
var title = $('section#shares .control-group input[name=title]');
var size = $('section#shares .control-group select[name=size]');
var type = $('section#shares .control-group select[name=type]');
var price = $('section#shares .control-group input[name=price]');
var amount = $('section#shares .control-group input[name=amount]');
var unit = $('section#shares .control-group select[name=unit]');
var discount_3 = $('input[name=discount-3]').val();
var discount_6 = $('input[name=discount-6]').val();
var discount_12 = $('input[name=discount-12]').val();
var errors = $('section#shares .control-group#errors');
var delivery_period = $('section#shares .control-group input[name=delivery_period]');
var delivery_period_es = $('section#shares .control-group input[name=delivery_period_es]');
var billing_period = $('section#shares .control-group input[name=billing_period]');
var billing_period_es = $('section#shares .control-group input[name=billing_period_es]');
var logoUploader = window.shareLogoUploader[shares.length];
var logoButtonId = "share-logo-" + shares.length;
shares.push({
title: title.val(),
currency: $('select[name=currency]').children(':selected').val(),
size: size.children(':selected').val(),
type: type.children(':selected').val(),
price: price.val() * 100.0,
unit: unit.children(':selected').val(),
amount: amount.val(),
discounts: {
'3': [discount_3, price.val() * discount_3 / 100.0],
'6': [discount_6, price.val() * discount_6 / 100.0],
'12': [discount_12, price.val() * discount_12 / 100.0]
},
delivery_period: delivery_period.val(),
delivery_period_es: delivery_period_es.val(),
billing_period: billing_period.val(),
billing_period_es: billing_period_es.val()
});
var newLogoButtonId = "share-logo-" + shares.length;
sharesGallery.push({
name: type.children(':selected').val() + "-" + size.children(':selected').val(),
logoUploader: logoUploader
})
$("#" + logoButtonId).css('display', 'none');
$("#" + logoButtonId).parent().append('<div id="' + newLogoButtonId + '"></div>');
window.shareLogoUploader[shares.length] = new qq.FineUploader({
element: $("#" + newLogoButtonId)[0],
request: {
endpoint: '/upload/farm/share/gallery'
},
autoUpload: false,
debug: true,
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'],
sizeLimit: 1024000 // 50 kB = 50 * 1024 bytes
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Select Logo'
}
});
console.log(shares);
return;
}
});
这会正确触发上传,我在服务器上获取请求并以这种方式处理它,然后服务器挂起等待永远不会到来的数据,重新 req.on Data naver 被触发。这是服务器端代码:
var fs = require('fs'), util = require('util'), uuid = require('node-uuid');
var uploadpath = __dirname + "/../public/uploads/";
var slugify = exports.slugify = function(value) {
return value.toLowerCase().replace(/-+/g, '').replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
};
// Route that takes the post upload request and sends the server response
exports.upload = function(req, res) {
winston.info("Upload parameters", [req.route.params[0], req.query.farm]);
uploadpath = __dirname + "/../public/uploads/";
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
switch(req.route.params[0]) {
case 'farm/logo':
uploadpath += "../farms/" + slugify(req.query.farm);
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
uploadpath += "/" + "logo." + req.header('x-file-name').split(".").pop();
break;
case 'farm/gallery/photo':
uploadpath += "../farms/" + slugify(req.query.farm);
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
uploadpath += "/gallery";
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
var fname = req.header('x-file-name');
uploadpath += "/" + fname;
break;
case 'farm/share/gallery':
uploadpath += "../farms/" + slugify(req.query.farm);
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
uploadpath += "/shares";
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
uploadpath += "/" + slugify(req.query.share);
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
uploadpath += "/gallery";
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
var fname = req.header('x-file-name');
uploadpath += "/" + fname;
break;
case 'courier/license':
case 'courier/registration':
uploadpath += "../couriers/" + slugify(req.query.courier);
if(!fs.existsSync(uploadpath)) {
fs.mkdirSync(uploadpath);
}
var fname = req.header('x-file-name');
uploadpath += "/" + fname;
break;
default:
var fname = req.header('x-file-name');
uploadpath += fname;
break;
}
winston.info("Uploading to ", uploadpath);
uploadFile(req, uploadpath, function(data) {
if(data.success)
res.send(JSON.stringify(data), {
'Content-Type' : 'text/plain'
}, 200);
else
res.send(JSON.stringify(data), {
'Content-Type' : 'text/plain'
}, 404);
});
}
// Mainfunction to recieve and process the file upload data asynchronously
var uploadFile = function(req, targetfile, callback) {
// Moves the uploaded file from temp directory to it's destination
// and calls the callback with the JSON-data that could be returned.
var moveToDestination = function(sourcefile, targetfile) {
moveFile(sourcefile, targetfile, function(err) {
if(!err)
callback({
success : true
});
else
callback({
success : false,
error : err
});
});
};
// Direct async xhr stream data upload, yeah baby.
if(req.xhr) {
// Be sure you can write to '/tmp/'
var tmpfile = '/tmp/' + uuid.v1();
// Open a temporary writestream
var ws = fs.createWriteStream(tmpfile);
ws.on('error', function(err) {
console.log("uploadFile() - req.xhr - could not open writestream.");
callback({
success : false,
error : "Sorry, could not open writestream."
});
});
ws.on('close', function(err) {
moveToDestination(tmpfile, targetfile);
});
// Writing filedata into writestream
req.on('data', function(data) {
ws.write(data);
});
req.on('end', function() {
ws.end();
});
}
// Old form-based upload
else {
moveToDestination(req.files.qqfile.path, targetfile);
}
};
// Moves a file asynchronously over partition borders
var moveFile = function(source, dest, callback) {
var is = fs.createReadStream(source)
is.on('error', function(err) {
console.log('moveFile() - Could not open readstream.', err);
callback('Sorry, could not open readstream.')
});
is.on('end', function() {
fs.unlinkSync(source);
callback();
});
var os = fs.createWriteStream(dest);
os.on('error', function(err) {
console.log('moveFile() - Could not open writestream.', err);
callback('Sorry, could not open writestream.');
});
is.pipe(os);
}
有人可以指出我正确的方向,以便为每组文件使用不同的参数上传文件吗?
先感谢您。