我正在自学Ajax,这节课需要在本地构建一个简单的文件上传表单。我在windows 7上运行XAMPP,并为http://test
设置了一个虚拟主机。书中的解决方案是使用node和一个几乎不为人知的名为“multipart”的包,该包应该解析表单数据,但在我身上却失败了。
我寻找了最适合这项工作的软件包,这看起来很强大。它确实很管用,我的文件可以上传到本地,我可以通过Ajax获得所有的细节。但是,它不适合书中简单的JS代码,这是为了在一个progress元素中显示上传进度。所以,我四处寻找,人们建议使用socket.io将进度信息发送回客户端页面。
我已经设法在本地使用了maforward,并且设法让socket.io使用了一些基本的教程。现在,我一辈子都不能让它们一起工作。当maforward在做它的事情时,我甚至不能从socket.io将一个简单的控制台日志消息发送回我的页面。
首先,这里是文件上传表单本身。upload.html页面中的脚本:
document.getElementById("submit").onclick = handleButtonPress;
var httpRequest;
function handleResponse() {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
document.getElementById("results").innerHTML = httpRequest.responseText;
}
}
function handleButtonPress(e) {
e.preventDefault();
var form = document.getElementById("myform");
var formData = new FormData(form);
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = handleResponse;
httpRequest.open("POST", form.action);
httpRequest.send(formData);
}
下面是相应的节点脚本(重要的部分是form.on('progress')
var http = require('http'),
util = require('util'),
formidable = require('formidable');
http.createServer(function(req, res) {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form.uploadDir = './files/';
form.keepExtensions = true;
form
.on('progress', function(bytesReceived, bytesExpected) {
console.log('Progress so far: '+(bytesReceived / bytesExpected * 100).toFixed(0)+"%");
})
.on('file', function(name, file) {
files.push([name, file]);
})
.on('error', function(err) {
console.log('ERROR!');
res.end();
})
.on('end', function() {
console.log('-> upload done');
res.writeHead(200, "OK", {
"Content-Type": "text/html", "Access-Control-Allow-Origin": "http://test"
});
res.end('received files: '+util.inspect(files));
});
form.parse(req);
} else {
res.writeHead(404, {'content-type': 'text/plain'});
res.end('404');
}
return;
}).listen(8080);
console.log('listening');
好了,一切都按预期运行。下面是一个最简单的socket.io脚本,我希望将它注入到前两个脚本中,以便将进度信息发送回我的页面。下面是客户端代码:
var socket = io.connect('http://test:8080');
socket.on('news', function(data){
console.log('server sent news:', data);
});
下面是服务器端节点脚本:
var http = require('http'),
fs = require('fs');
var server = http.createServer(function(req, res) {
fs.createReadStream('./socket.html').pipe(res);
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
socket.emit('news', {hello: "world"});
});
server.listen(8080);
因此,这本身工作得很好,但是当我尝试将www.example.com代码放在表单中时,问题就来socket.io了....我尝试过将它放在任何可能有意义的地方,我也尝试过fs.readFile
的异步模式,但它只是不会发送任何东西回客户端-同时,文件上传部分仍然工作正常。我需要在两个包之间建立某种握手吗?请帮助我解决这个问题。我是一个前端人员,所以我对后端的内容不太熟悉。我将暂时把这个放在一边,然后继续学习其他课程。
1条答案
按热度按时间bvuwiixz1#
也许你可以为一个客户端创建一个房间,然后将百分比广播到这个房间。
我在这里解释了一下:如何在Node.js中连接强大的文件上传到socket.io